Merge branch 'graphics-backends-improvements'

This commit is contained in:
Colin Snover 2017-10-15 13:26:39 -05:00
commit 7d8d2f80fb
35 changed files with 1283 additions and 1222 deletions

View File

@ -254,4 +254,30 @@ void DefaultEventManager::pushEvent(const Common::Event &event) {
_artificialEventSource.addEvent(event);
}
void DefaultEventManager::purgeMouseEvents() {
_dispatcher.dispatch();
Common::Queue<Common::Event> filteredQueue;
while (!_eventQueue.empty()) {
Common::Event event = _eventQueue.pop();
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONDOWN:
case Common::EVENT_RBUTTONUP:
case Common::EVENT_WHEELUP:
case Common::EVENT_WHEELDOWN:
case Common::EVENT_MBUTTONDOWN:
case Common::EVENT_MBUTTONUP:
// do nothing
break;
default:
filteredQueue.push(event);
break;
}
}
_eventQueue = filteredQueue;
}
#endif // !defined(DISABLE_DEFAULT_EVENTMANAGER)

View File

@ -80,6 +80,7 @@ public:
virtual void init();
virtual bool pollEvent(Common::Event &event);
virtual void pushEvent(const Common::Event &event);
virtual void purgeMouseEvents() override;
virtual Common::Point getMousePos() const { return _mousePos; }
virtual int getButtonState() const { return _buttonState; }

View File

@ -75,7 +75,7 @@ static uint32 convUTF8ToUTF32(const char *src) {
#endif
SdlEventSource::SdlEventSource()
: EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0)
: EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0), _queuedFakeMouseMove(false)
#if SDL_VERSION_ATLEAST(2, 0, 0)
, _queuedFakeKeyUp(false), _fakeKeyUp()
#endif
@ -158,7 +158,7 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
} else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
return key;
} else if (unicode) {
// Return unicode in case it's stil set and wasn't filtered.
// Return unicode in case it's still set and wasn't filtered.
return unicode;
} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
return key & ~0x20;
@ -169,14 +169,15 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
}
}
void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
bool SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
event.mouse.x = x;
event.mouse.y = y;
if (_graphicsManager) {
_graphicsManager->notifyMousePos(Common::Point(x, y));
_graphicsManager->transformMouseCoordinates(event.mouse);
return _graphicsManager->notifyMousePosition(event.mouse);
}
return true;
}
bool SdlEventSource::handleKbdMouse(Common::Event &event) {
@ -308,8 +309,7 @@ bool SdlEventSource::handleKbdMouse(Common::Event &event) {
if (_km.x != oldKmX || _km.y != oldKmY) {
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
return true;
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
}
}
}
@ -508,6 +508,12 @@ bool SdlEventSource::pollEvent(Common::Event &event) {
return true;
}
if (_queuedFakeMouseMove) {
event = _fakeMouseMove;
_queuedFakeMouseMove = false;
return true;
}
SDL_Event ev;
while (SDL_PollEvent(&ev)) {
preprocessEvents(&ev);
@ -549,7 +555,9 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
// with a mouse wheel event. However, SDL2 does not supply
// these, thus we use whatever we got last time. It seems
// these are always stored in _km.x, _km.y.
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
if (!processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER)) {
return false;
}
if (yDir < 0) {
event.type = Common::EVENT_WHEELDOWN;
return true;
@ -740,12 +748,12 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
bool SdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, ev.motion.x, ev.motion.y);
// update KbdMouse
_km.x = ev.motion.x * MULTIPLIER;
_km.y = ev.motion.y * MULTIPLIER;
return true;
return processMouseEvent(event, ev.motion.x, ev.motion.y);
}
bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
@ -766,12 +774,11 @@ bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event)
else
return false;
processMouseEvent(event, ev.button.x, ev.button.y);
// update KbdMouse
_km.x = ev.button.x * MULTIPLIER;
_km.y = ev.button.y * MULTIPLIER;
return true;
return processMouseEvent(event, ev.button.x, ev.button.y);
}
bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
@ -785,21 +792,21 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
#endif
else
return false;
processMouseEvent(event, ev.button.x, ev.button.y);
// update KbdMouse
_km.x = ev.button.x * MULTIPLIER;
_km.y = ev.button.y * MULTIPLIER;
return true;
return processMouseEvent(event, ev.button.x, ev.button.y);
}
bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONDOWN;
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONDOWN;
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYDOWN;
switch (ev.jbutton.button) {
@ -820,17 +827,17 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
}
return true;
}
return true;
}
bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONUP;
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONUP;
processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYUP;
switch (ev.jbutton.button) {
@ -851,8 +858,8 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
}
return true;
}
return true;
}
bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
@ -968,9 +975,8 @@ bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
}
// Nap center (space) to tab (default action )
// Map center (space) to tab (default action)
// I wanted to map the calendar button but the calendar comes up
//
else if (ev.key.keysym.sym == SDLK_SPACE) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_TAB;
@ -1003,6 +1009,12 @@ void SdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) {
_km.joy_y = 0;
}
void SdlEventSource::fakeWarpMouse(const int x, const int y) {
_queuedFakeMouseMove = true;
_fakeMouseMove.type = Common::EVENT_MOUSEMOVE;
_fakeMouseMove.mouse = Common::Point(x, y);
}
bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
if (_graphicsManager) {
_graphicsManager->notifyResize(w, h);

View File

@ -51,6 +51,12 @@ public:
*/
virtual void resetKeyboardEmulation(int16 x_max, int16 y_max);
/**
* Emulates a mouse movement that would normally be caused by a mouse warp
* of the system mouse.
*/
void fakeWarpMouse(const int x, const int y);
protected:
/** @name Keyboard mouse emulation
* Disabled by fingolfin 2004-12-18.
@ -117,7 +123,7 @@ protected:
* Assigns the mouse coords to the mouse event. Furthermore notify the
* graphics manager about the position change.
*/
virtual void processMouseEvent(Common::Event &event, int x, int y);
virtual bool processMouseEvent(Common::Event &event, int x, int y);
/**
* Remaps key events. This allows platforms to configure
@ -156,6 +162,18 @@ protected:
*/
SDLKey obtainKeycode(const SDL_keysym keySym);
/**
* Whether _fakeMouseMove contains an event we need to send.
*/
bool _queuedFakeMouseMove;
/**
* A fake mouse motion event sent when the graphics manager is told to warp
* the mouse but the system mouse is unable to be warped (e.g. because the
* window is not focused).
*/
Common::Event _fakeMouseMove;
#if SDL_VERSION_ATLEAST(2, 0, 0)
/**
* Whether _fakeKeyUp contains an event we need to send.

View File

@ -487,14 +487,6 @@ bool DINGUXSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
}
}
SurfaceSdlGraphicsManager::MousePos *DINGUXSdlGraphicsManager::getMouseCurState() {
return &_mouseCurState;
}
SurfaceSdlGraphicsManager::VideoState *DINGUXSdlGraphicsManager::getVideoMode() {
return &_videoMode;
}
void DINGUXSdlGraphicsManager::warpMouse(int x, int y) {
if (_mouseCurState.x != x || _mouseCurState.y != y) {
if (_videoMode.mode == GFX_HALF && !_overlayVisible) {

View File

@ -36,26 +36,23 @@ class DINGUXSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
DINGUXSdlGraphicsManager(SdlEventSource *boss, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
bool getFeatureState(OSystem::Feature f);
int getDefaultGraphicsMode() const;
bool hasFeature(OSystem::Feature f) const override;
void setFeatureState(OSystem::Feature f, bool enable) override;
bool getFeatureState(OSystem::Feature f) override;
int getDefaultGraphicsMode() const override;
void initSize(uint w, uint h);
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
bool setGraphicsMode(const char *name);
bool setGraphicsMode(int mode);
void setGraphicsModeIntern();
void internUpdateScreen();
void showOverlay();
void hideOverlay();
bool loadGFXMode();
void drawMouse();
void undrawMouse();
virtual void warpMouse(int x, int y);
SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
SurfaceSdlGraphicsManager::VideoState *getVideoMode();
void initSize(uint w, uint h) override;
const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
bool setGraphicsMode(const char *name) override;
bool setGraphicsMode(int mode) override;
void setGraphicsModeIntern() override;
void internUpdateScreen() override;
void showOverlay() override;
void hideOverlay() override;
bool loadGFXMode() override;
void drawMouse() override;
void undrawMouse() override;
void warpMouse(int x, int y) override;
virtual void transformMouseCoordinates(Common::Point &point);
};

View File

@ -477,7 +477,7 @@ bool GPHGraphicsManager::loadGFXMode() {
return true;
}
bool GPHGraphicsManager::hasFeature(OSystem::Feature f) {
bool GPHGraphicsManager::hasFeature(OSystem::Feature f) const {
return
(f == OSystem::kFeatureAspectRatioCorrection) ||
(f == OSystem::kFeatureCursorPalette);
@ -497,7 +497,7 @@ void GPHGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
}
bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) {
bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) const {
assert(_transactionMode == kTransactionNone);
switch (f) {
@ -510,14 +510,6 @@ bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) {
}
}
SurfaceSdlGraphicsManager::MousePos *GPHGraphicsManager::getMouseCurState() {
return &_mouseCurState;
}
SurfaceSdlGraphicsManager::VideoState *GPHGraphicsManager::getVideoMode() {
return &_videoMode;
}
void GPHGraphicsManager::warpMouse(int x, int y) {
if (_mouseCurState.x != x || _mouseCurState.y != y) {
if (_videoMode.mode == GFX_HALF && !_overlayVisible) {

View File

@ -35,26 +35,23 @@ class GPHGraphicsManager : public SurfaceSdlGraphicsManager {
public:
GPHGraphicsManager(SdlEventSource *boss, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
bool getFeatureState(OSystem::Feature f);
int getDefaultGraphicsMode() const;
bool hasFeature(OSystem::Feature f) const override;
void setFeatureState(OSystem::Feature f, bool enable) override;
bool getFeatureState(OSystem::Feature f) const;
int getDefaultGraphicsMode() const override;
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
bool setGraphicsMode(const char *name);
bool setGraphicsMode(int mode);
void setGraphicsModeIntern();
void internUpdateScreen();
void showOverlay();
void hideOverlay();
bool loadGFXMode();
void drawMouse();
void undrawMouse();
virtual void warpMouse(int x, int y);
SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
SurfaceSdlGraphicsManager::VideoState *getVideoMode();
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
bool setGraphicsMode(const char *name) override;
bool setGraphicsMode(int mode) override;
void setGraphicsModeIntern() override;
void internUpdateScreen() override;
void showOverlay() override;
void hideOverlay() override;
bool loadGFXMode() override;
void drawMouse() override;
void undrawMouse() override;
void warpMouse(int x, int y) override;
virtual void transformMouseCoordinates(Common::Point &point);
};

View File

@ -38,9 +38,9 @@ class GraphicsManager : public PaletteManager {
public:
virtual ~GraphicsManager() {}
virtual bool hasFeature(OSystem::Feature f) = 0;
virtual bool hasFeature(OSystem::Feature f) const = 0;
virtual void setFeatureState(OSystem::Feature f, bool enable) = 0;
virtual bool getFeatureState(OSystem::Feature f) = 0;
virtual bool getFeatureState(OSystem::Feature f) const = 0;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const = 0;
virtual int getDefaultGraphicsMode() const = 0;
@ -65,10 +65,10 @@ public:
virtual void beginGFXTransaction() = 0;
virtual OSystem::TransactionError endGFXTransaction() = 0;
virtual int16 getHeight() = 0;
virtual int16 getWidth() = 0;
virtual int16 getHeight() const = 0;
virtual int16 getWidth() const = 0;
virtual void setPalette(const byte *colors, uint start, uint num) = 0;
virtual void grabPalette(byte *colors, uint start, uint num) = 0;
virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) = 0;
virtual Graphics::Surface *lockScreen() = 0;
virtual void unlockScreen() = 0;
@ -82,10 +82,10 @@ public:
virtual void hideOverlay() = 0;
virtual Graphics::PixelFormat getOverlayFormat() const = 0;
virtual void clearOverlay() = 0;
virtual void grabOverlay(void *buf, int pitch) = 0;
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h)= 0;
virtual int16 getOverlayHeight() = 0;
virtual int16 getOverlayWidth() = 0;
virtual void grabOverlay(void *buf, int pitch) const = 0;
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) = 0;
virtual int16 getOverlayHeight() const = 0;
virtual int16 getOverlayWidth() const = 0;
virtual bool showMouse(bool visible) = 0;
virtual void warpMouse(int x, int y) = 0;

View File

@ -29,18 +29,18 @@ class LinuxmotoSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual void initSize(uint w, uint h);
virtual void setGraphicsModeIntern();
virtual bool setGraphicsMode(int mode);
virtual void internUpdateScreen();
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool loadGFXMode();
virtual void drawMouse();
virtual void undrawMouse();
virtual void showOverlay();
virtual void hideOverlay();
virtual void warpMouse(int x, int y);
virtual void initSize(uint w, uint h) override;
virtual void setGraphicsModeIntern() override;
virtual bool setGraphicsMode(int mode) override;
virtual void internUpdateScreen() override;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
virtual int getDefaultGraphicsMode() const override;
virtual bool loadGFXMode() override;
virtual void drawMouse() override;
virtual void undrawMouse() override;
virtual void showOverlay() override;
virtual void hideOverlay() override;
virtual void warpMouse(int x, int y) override;
virtual void transformMouseCoordinates(Common::Point &point);
};

View File

@ -32,7 +32,7 @@ public:
MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
protected:
virtual bool loadGFXMode();
virtual bool loadGFXMode() override;
};
#endif

View File

@ -31,55 +31,55 @@ class NullGraphicsManager : public GraphicsManager {
public:
virtual ~NullGraphicsManager() {}
bool hasFeature(OSystem::Feature f) { return false; }
void setFeatureState(OSystem::Feature f, bool enable) {}
bool getFeatureState(OSystem::Feature f) { return false; }
bool hasFeature(OSystem::Feature f) const override { return false; }
void setFeatureState(OSystem::Feature f, bool enable) override {}
bool getFeatureState(OSystem::Feature f) const override { return false; }
const OSystem::GraphicsMode *getSupportedGraphicsModes() const { return s_noGraphicsModes; }
int getDefaultGraphicsMode() const { return 0; }
bool setGraphicsMode(int mode) { return true; }
void resetGraphicsScale(){}
int getGraphicsMode() const { return 0; }
inline Graphics::PixelFormat getScreenFormat() const {
const OSystem::GraphicsMode *getSupportedGraphicsModes() const override { return s_noGraphicsModes; }
int getDefaultGraphicsMode() const override { return 0; }
bool setGraphicsMode(int mode) override { return true; }
void resetGraphicsScale() override {}
int getGraphicsMode() const override { return 0; }
inline Graphics::PixelFormat getScreenFormat() const override {
return Graphics::PixelFormat::createFormatCLUT8();
}
inline Common::List<Graphics::PixelFormat> getSupportedFormats() const {
inline Common::List<Graphics::PixelFormat> getSupportedFormats() const override {
Common::List<Graphics::PixelFormat> list;
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
return list;
}
void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) {}
virtual int getScreenChangeID() const { return 0; }
void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override {}
virtual int getScreenChangeID() const override { return 0; }
void beginGFXTransaction() {}
OSystem::TransactionError endGFXTransaction() { return OSystem::kTransactionSuccess; }
void beginGFXTransaction() override {}
OSystem::TransactionError endGFXTransaction() override { return OSystem::kTransactionSuccess; }
int16 getHeight() { return 0; }
int16 getWidth() { return 0; }
void setPalette(const byte *colors, uint start, uint num) {}
void grabPalette(byte *colors, uint start, uint num) {}
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {}
Graphics::Surface *lockScreen() { return NULL; }
void unlockScreen() {}
void fillScreen(uint32 col) {}
void updateScreen() {}
void setShakePos(int shakeOffset) {}
void setFocusRectangle(const Common::Rect& rect) {}
void clearFocusRectangle() {}
int16 getHeight() const override { return 0; }
int16 getWidth() const override { return 0; }
void setPalette(const byte *colors, uint start, uint num) override {}
void grabPalette(byte *colors, uint start, uint num) const override {}
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override {}
Graphics::Surface *lockScreen() override { return NULL; }
void unlockScreen() override {}
void fillScreen(uint32 col) override {}
void updateScreen() override {}
void setShakePos(int shakeOffset) override {}
void setFocusRectangle(const Common::Rect& rect) override {}
void clearFocusRectangle() override {}
void showOverlay() {}
void hideOverlay() {}
Graphics::PixelFormat getOverlayFormat() const { return Graphics::PixelFormat(); }
void clearOverlay() {}
void grabOverlay(void *buf, int pitch) {}
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {}
int16 getOverlayHeight() { return 0; }
int16 getOverlayWidth() { return 0; }
void showOverlay() override {}
void hideOverlay() override {}
Graphics::PixelFormat getOverlayFormat() const override { return Graphics::PixelFormat(); }
void clearOverlay() override {}
void grabOverlay(void *buf, int pitch) const override {}
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override {}
int16 getOverlayHeight() const override { return 0; }
int16 getOverlayWidth() const override { return 0; }
bool showMouse(bool visible) { return !visible; }
void warpMouse(int x, int y) {}
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) {}
void setCursorPalette(const byte *colors, uint start, uint num) {}
bool showMouse(bool visible) override { return !visible; }
void warpMouse(int x, int y) override {}
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override {}
void setCursorPalette(const byte *colors, uint start, uint num) override {}
};
#endif

View File

@ -53,14 +53,12 @@ namespace OpenGL {
OpenGLGraphicsManager::OpenGLGraphicsManager()
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
_pipeline(nullptr),
_outputScreenWidth(0), _outputScreenHeight(0), _displayX(0), _displayY(0),
_displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
_defaultFormat(), _defaultFormatAlpha(),
_gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
_overlayVisible(false), _cursor(nullptr),
_cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0),
_cursor(nullptr),
_cursorHotspotX(0), _cursorHotspotY(0),
_cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
_cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false),
_forceRedraw(false)
_cursorKeyColor(0), _cursorDontScale(false), _cursorPaletteEnabled(false)
#ifdef USE_OSD
, _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
_osdIconSurface(nullptr)
@ -83,7 +81,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
#endif
}
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureAspectRatioCorrection:
case OSystem::kFeatureCursorPalette:
@ -129,7 +127,7 @@ void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
}
bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) {
bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureAspectRatioCorrection:
return _currentState.aspectRatioCorrection;
@ -220,10 +218,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
#endif
do {
uint requestedWidth = _currentState.gameWidth;
uint requestedHeight = _currentState.gameHeight;
const uint desiredAspect = getDesiredGameScreenAspect();
requestedHeight = intToFrac(requestedWidth) / desiredAspect;
const uint desiredAspect = getDesiredGameAspectRatio();
const uint requestedWidth = _currentState.gameWidth;
const uint requestedHeight = intToFrac(requestedWidth) / desiredAspect;
if (!loadVideoMode(requestedWidth, requestedHeight,
#ifdef USE_RGB_COLOR
@ -317,7 +314,7 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
// Update our display area and cursor scaling. This makes sure we pick up
// aspect ratio correction and game screen changes correctly.
recalculateDisplayArea();
recalculateDisplayAreas();
recalculateCursorScaling();
// Something changed, so update the screen change ID.
@ -347,11 +344,11 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi
_currentState.gameHeight = height;
}
int16 OpenGLGraphicsManager::getWidth() {
int16 OpenGLGraphicsManager::getWidth() const {
return _currentState.gameWidth;
}
int16 OpenGLGraphicsManager::getHeight() {
int16 OpenGLGraphicsManager::getHeight() const {
return _currentState.gameHeight;
}
@ -392,6 +389,7 @@ void OpenGLGraphicsManager::updateScreen() {
// We only update the screen when there actually have been any changes.
if ( !_forceRedraw
&& !_cursorNeedsRedraw
&& !_gameScreen->isDirty()
&& !(_overlayVisible && _overlay->isDirty())
&& !(_cursorVisible && _cursor && _cursor->isDirty())
@ -401,7 +399,6 @@ void OpenGLGraphicsManager::updateScreen() {
) {
return;
}
_forceRedraw = false;
// Update changes to textures.
_gameScreen->updateGLTexture();
@ -420,14 +417,14 @@ void OpenGLGraphicsManager::updateScreen() {
_backBuffer.enableScissorTest(true);
}
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_gameDrawRect.height() / _gameScreen->getHeight();
// First step: Draw the (virtual) game screen.
g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top + shakeOffset, _gameDrawRect.width(), _gameDrawRect.height());
// Second step: Draw the overlay if visible.
if (_overlayVisible) {
g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _overlayDrawRect.width(), _overlayDrawRect.height());
}
// Third step: Draw the cursor if visible.
@ -437,8 +434,8 @@ void OpenGLGraphicsManager::updateScreen() {
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
_cursorDisplayX - _cursorHotspotXScaled,
_cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
_cursorX - _cursorHotspotXScaled,
_cursorY - _cursorHotspotYScaled + cursorOffset,
_cursorWidthScaled, _cursorHeightScaled);
}
@ -464,8 +461,8 @@ void OpenGLGraphicsManager::updateScreen() {
// Set the OSD transparency.
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
int dstX = (_outputScreenWidth - _osdMessageSurface->getWidth()) / 2;
int dstY = (_outputScreenHeight - _osdMessageSurface->getHeight()) / 2;
int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
// Draw the OSD texture.
g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
@ -481,7 +478,7 @@ void OpenGLGraphicsManager::updateScreen() {
}
if (_osdIconSurface) {
int dstX = _outputScreenWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
int dstX = _windowWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
int dstY = kOSDIconTopMargin;
// Draw the OSD icon texture.
@ -490,6 +487,8 @@ void OpenGLGraphicsManager::updateScreen() {
}
#endif
_cursorNeedsRedraw = false;
_forceRedraw = false;
refreshScreen();
}
@ -507,7 +506,7 @@ void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
void OpenGLGraphicsManager::clearFocusRectangle() {
}
int16 OpenGLGraphicsManager::getOverlayWidth() {
int16 OpenGLGraphicsManager::getOverlayWidth() const {
if (_overlay) {
return _overlay->getWidth();
} else {
@ -515,7 +514,7 @@ int16 OpenGLGraphicsManager::getOverlayWidth() {
}
}
int16 OpenGLGraphicsManager::getOverlayHeight() {
int16 OpenGLGraphicsManager::getOverlayHeight() const {
if (_overlay) {
return _overlay->getHeight();
} else {
@ -523,22 +522,6 @@ int16 OpenGLGraphicsManager::getOverlayHeight() {
}
}
void OpenGLGraphicsManager::showOverlay() {
_overlayVisible = true;
_forceRedraw = true;
// Update cursor position.
setMousePosition(_cursorX, _cursorY);
}
void OpenGLGraphicsManager::hideOverlay() {
_overlayVisible = false;
_forceRedraw = true;
// Update cursor position.
setMousePosition(_cursorX, _cursorY);
}
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
return _overlay->getFormat();
}
@ -551,7 +534,7 @@ void OpenGLGraphicsManager::clearOverlay() {
_overlay->fill(0);
}
void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) const {
const Graphics::Surface *overlayData = _overlay->getSurface();
const byte *src = (const byte *)overlayData->getPixels();
@ -564,55 +547,6 @@ void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
}
}
bool OpenGLGraphicsManager::showMouse(bool visible) {
// In case the mouse cursor visibility changed we need to redraw the whole
// screen even when nothing else changed.
if (_cursorVisible != visible) {
_forceRedraw = true;
}
bool last = _cursorVisible;
_cursorVisible = visible;
return last;
}
void OpenGLGraphicsManager::warpMouse(int x, int y) {
int16 currentX = _cursorX;
int16 currentY = _cursorY;
adjustMousePosition(currentX, currentY);
// Check whether the (virtual) coordinate actually changed. If not, then
// simply do nothing. This avoids ugly "jittering" due to the actual
// output screen having a bigger resolution than the virtual coordinates.
if (currentX == x && currentY == y) {
return;
}
// Scale the virtual coordinates into actual physical coordinates.
if (_overlayVisible) {
if (!_overlay) {
return;
}
// It might be confusing that we actually have to handle something
// here when the overlay is visible. This is because for very small
// resolutions we have a minimal overlay size and have to adjust
// for that.
x = (x * _outputScreenWidth) / _overlay->getWidth();
y = (y * _outputScreenHeight) / _overlay->getHeight();
} else {
if (!_gameScreen) {
return;
}
x = (x * _outputScreenWidth) / _gameScreen->getWidth();
y = (y * _outputScreenHeight) / _gameScreen->getHeight();
}
setMousePosition(x, y);
setInternalMousePosition(x, y);
}
namespace {
template<typename DstPixel, typename SrcPixel>
void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstPitch, uint srcPitch, SrcPixel keyColor, DstPixel alphaMask) {
@ -633,6 +567,18 @@ void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstP
} // End of anonymous namespace
void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
_cursorKeyColor = keycolor;
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;
_cursorDontScale = dontScale;
if (!w || !h) {
delete _cursor;
_cursor = nullptr;
return;
}
Graphics::PixelFormat inputFormat;
#ifdef USE_RGB_COLOR
if (format) {
@ -668,11 +614,6 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
_cursor->enableLinearFiltering(_currentState.filtering);
}
_cursorKeyColor = keycolor;
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;
_cursorDontScale = dontScale;
_cursor->allocate(w, h);
if (inputFormat.bytesPerPixel == 1) {
// For CLUT8 cursors we can simply copy the input data into the
@ -720,7 +661,6 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
updateCursorPalette();
}
// Update the scaling.
recalculateCursorScaling();
}
@ -765,8 +705,8 @@ void OpenGLGraphicsManager::osdMessageUpdateSurface() {
}
// Clip the rect
width = MIN<uint>(width, _displayWidth);
height = MIN<uint>(height, _displayHeight);
width = MIN<uint>(width, _gameDrawRect.width());
height = MIN<uint>(height, _gameDrawRect.height());
delete _osdMessageSurface;
_osdMessageSurface = nullptr;
@ -849,16 +789,13 @@ void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num)
updateCursorPalette();
}
void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
assert(_gameScreen->hasPalette());
memcpy(colors, _gamePalette + start * 3, num * 3);
}
void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
_outputScreenWidth = width;
_outputScreenHeight = height;
void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
// Setup backbuffer size.
_backBuffer.setDimensions(width, height);
@ -873,7 +810,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
// anyway. Thus, it should not be a real issue for modern hardware.
if ( overlayWidth > (uint)g_context.maxTextureSize
|| overlayHeight > (uint)g_context.maxTextureSize) {
const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
if (outputAspect > (frac_t)FRAC_ONE) {
overlayWidth = g_context.maxTextureSize;
@ -906,7 +843,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
_overlay->fill(0);
// Re-setup the scaling for the screen and cursor
recalculateDisplayArea();
recalculateDisplayAreas();
recalculateCursorScaling();
// Something changed, so update the screen change ID.
@ -960,8 +897,8 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
// Refresh the output screen dimensions if some are set up.
if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
if (_windowWidth != 0 && _windowHeight != 0) {
handleResize(_windowWidth, _windowHeight);
}
// TODO: Should we try to convert textures into one of those formats if
@ -1031,46 +968,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
g_context.reset();
}
void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
if (_overlayVisible) {
// It might be confusing that we actually have to handle something
// here when the overlay is visible. This is because for very small
// resolutions we have a minimal overlay size and have to adjust
// for that.
// This can also happen when the overlay is smaller than the actual
// display size because of texture size limitations.
if (_overlay) {
x = (x * _overlay->getWidth()) / _outputScreenWidth;
y = (y * _overlay->getHeight()) / _outputScreenHeight;
}
} else if (_gameScreen) {
const int16 width = _gameScreen->getWidth();
const int16 height = _gameScreen->getHeight();
x = (x * width) / (int)_outputScreenWidth;
y = (y * height) / (int)_outputScreenHeight;
}
}
void OpenGLGraphicsManager::setMousePosition(int x, int y) {
// Whenever the mouse position changed we force a screen redraw to reflect
// changes properly.
if (_cursorX != x || _cursorY != y) {
_forceRedraw = true;
}
_cursorX = x;
_cursorY = y;
if (_overlayVisible) {
_cursorDisplayX = x;
_cursorDisplayY = y;
} else {
_cursorDisplayX = _displayX + (x * _displayWidth) / _outputScreenWidth;
_cursorDisplayY = _displayY + (y * _displayHeight) / _outputScreenHeight;
}
}
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
GLenum glIntFormat, glFormat, glType;
if (format.bytesPerPixel == 1) {
@ -1191,51 +1088,34 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
}
}
frac_t OpenGLGraphicsManager::getDesiredGameScreenAspect() const {
const uint width = _currentState.gameWidth;
const uint height = _currentState.gameHeight;
bool OpenGLGraphicsManager::gameNeedsAspectRatioCorrection() const {
if (_currentState.aspectRatioCorrection) {
const uint width = getWidth();
const uint height = getHeight();
// In case we enable aspect ratio correction we force a 4/3 ratio.
// But just for 320x200 and 640x400 games, since other games do not need
// this.
if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
return intToFrac(4) / 3;
}
return (width == 320 && height == 200) || (width == 640 && height == 400);
}
return intToFrac(width) / height;
return false;
}
void OpenGLGraphicsManager::recalculateDisplayArea() {
if (!_gameScreen || _outputScreenHeight == 0) {
void OpenGLGraphicsManager::recalculateDisplayAreas() {
if (!_gameScreen) {
return;
}
const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
const frac_t desiredAspect = getDesiredGameScreenAspect();
_displayWidth = _outputScreenWidth;
_displayHeight = _outputScreenHeight;
// Adjust one dimension for mantaining the aspect ratio.
if (outputAspect < desiredAspect) {
_displayHeight = intToFrac(_displayWidth) / desiredAspect;
} else if (outputAspect > desiredAspect) {
_displayWidth = fracToInt(_displayHeight * desiredAspect);
}
// We center the screen in the middle for now.
_displayX = (_outputScreenWidth - _displayWidth ) / 2;
_displayY = (_outputScreenHeight - _displayHeight) / 2;
WindowedGraphicsManager::recalculateDisplayAreas();
// Setup drawing limitation for game graphics.
// This involves some trickery because OpenGL's viewport coordinate system
// is upside down compared to ours.
_backBuffer.setScissorBox(_displayX,
_outputScreenHeight - _displayHeight - _displayY,
_displayWidth,
_displayHeight);
_backBuffer.setScissorBox(_gameDrawRect.left,
_windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
_gameDrawRect.width(),
_gameDrawRect.height());
// Update the cursor position to adjust for new display area.
setMousePosition(_cursorX, _cursorY);
@ -1272,8 +1152,8 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
// In case scaling is actually enabled we will scale the cursor according
// to the game screen.
if (!_cursorDontScale) {
const frac_t screenScaleFactorX = intToFrac(_displayWidth) / _gameScreen->getWidth();
const frac_t screenScaleFactorY = intToFrac(_displayHeight) / _gameScreen->getHeight();
const frac_t screenScaleFactorX = intToFrac(_gameDrawRect.width()) / _gameScreen->getWidth();
const frac_t screenScaleFactorY = intToFrac(_gameDrawRect.height()) / _gameScreen->getHeight();
_cursorHotspotXScaled = fracToInt(_cursorHotspotXScaled * screenScaleFactorX);
_cursorWidthScaled = fracToInt(_cursorWidthScaled * screenScaleFactorX);
@ -1284,14 +1164,14 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
}
#ifdef USE_OSD
const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
const Graphics::Font *OpenGLGraphicsManager::getFontOSD() const {
return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
}
#endif
bool OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
const uint width = _outputScreenWidth;
const uint height = _outputScreenHeight;
const uint width = _windowWidth;
const uint height = _windowHeight;
// A line of a BMP image must have a size divisible by 4.
// We calculate the padding bytes needed here.

View File

@ -25,7 +25,7 @@
#include "backends/graphics/opengl/opengl-sys.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "backends/graphics/graphics.h"
#include "backends/graphics/windowed.h"
#include "common/frac.h"
#include "common/mutex.h"
@ -53,74 +53,69 @@ enum {
GFX_OPENGL = 0
};
class OpenGLGraphicsManager : virtual public GraphicsManager {
class OpenGLGraphicsManager : virtual public WindowedGraphicsManager {
public:
OpenGLGraphicsManager();
virtual ~OpenGLGraphicsManager();
// GraphicsManager API
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
virtual bool hasFeature(OSystem::Feature f) const override;
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
virtual bool getFeatureState(OSystem::Feature f) const override;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
virtual int getDefaultGraphicsMode() const override;
virtual bool setGraphicsMode(int mode) override;
virtual int getGraphicsMode() const override;
virtual void resetGraphicsScale() {}
virtual void resetGraphicsScale() override {}
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
virtual Graphics::PixelFormat getScreenFormat() const override;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override = 0;
#endif
virtual void beginGFXTransaction();
virtual OSystem::TransactionError endGFXTransaction();
virtual void beginGFXTransaction() override;
virtual OSystem::TransactionError endGFXTransaction() override;
virtual int getScreenChangeID() const;
virtual int getScreenChangeID() const override;
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
virtual int16 getWidth();
virtual int16 getHeight();
virtual int16 getWidth() const override;
virtual int16 getHeight() const override;
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
virtual void fillScreen(uint32 col);
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
virtual void fillScreen(uint32 col) override;
virtual void setShakePos(int shakeOffset);
virtual void setShakePos(int shakeOffset) override;
virtual void updateScreen();
virtual void updateScreen() override;
virtual Graphics::Surface *lockScreen();
virtual void unlockScreen();
virtual Graphics::Surface *lockScreen() override;
virtual void unlockScreen() override;
virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle();
virtual void setFocusRectangle(const Common::Rect& rect) override;
virtual void clearFocusRectangle() override;
virtual int16 getOverlayWidth();
virtual int16 getOverlayHeight();
virtual int16 getOverlayWidth() const override;
virtual int16 getOverlayHeight() const override;
virtual void showOverlay();
virtual void hideOverlay();
virtual Graphics::PixelFormat getOverlayFormat() const override;
virtual Graphics::PixelFormat getOverlayFormat() const;
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
virtual void clearOverlay() override;
virtual void grabOverlay(void *buf, int pitch) const override;
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
virtual void clearOverlay();
virtual void grabOverlay(void *buf, int pitch);
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) override;
virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual void displayMessageOnOSD(const char *msg);
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
virtual void displayMessageOnOSD(const char *msg) override;
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
// PaletteManager interface
virtual void setPalette(const byte *colors, uint start, uint num);
virtual void grabPalette(byte *colors, uint start, uint num);
virtual void setPalette(const byte *colors, uint start, uint num) override;
virtual void grabPalette(byte *colors, uint start, uint num) const override;
protected:
/**
@ -128,15 +123,6 @@ protected:
*/
bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
/**
* Set up the actual screen size available for the OpenGL code to do any
* drawing.
*
* @param width The width of the screen.
* @param height The height of the screen.
*/
void setActualScreenSize(uint width, uint height);
/**
* Sets the OpenGL (ES) type the graphics manager shall work with.
*
@ -166,33 +152,6 @@ protected:
*/
void notifyContextDestroy();
/**
* Adjust the physical mouse coordinates according to the currently visible screen.
*/
void adjustMousePosition(int16 &x, int16 &y);
/**
* Set up the mouse position for graphics output.
*
* @param x X coordinate in physical coordinates.
* @param y Y coordinate in physical coordinates.
*/
void setMousePosition(int x, int y);
/**
* Query the mouse position in physical coordinates.
*/
void getMousePosition(int16 &x, int16 &y) const { x = _cursorX; y = _cursorY; }
/**
* Set up the mouse position for the (event) system.
*
* @param x X coordinate in physical coordinates.
* @param y Y coordinate in physical coordinates.
*/
virtual void setInternalMousePosition(int x, int y) = 0;
private:
/**
* Create a surface with the specified pixel format.
*
@ -241,7 +200,7 @@ private:
};
/**
* The currently setup video state.
* The currently set up video state.
*/
VideoState _currentState;
@ -292,8 +251,7 @@ protected:
virtual void refreshScreen() = 0;
/**
* Save a screenshot of the full display as BMP to the given file. This
* uses Common::DumpFile for writing the screenshot.
* Saves a screenshot of the entire window, excluding window decorations.
*
* @param filename The output filename.
* @return true on success, false otherwise
@ -334,7 +292,6 @@ protected:
*/
virtual void *getProcAddress(const char *name) const = 0;
private:
/**
* Try to determine the internal parameters for a given pixel format.
*
@ -342,49 +299,9 @@ private:
*/
bool getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const;
//
// Actual hardware screen
//
/**
* The width of the physical output.
*/
uint _outputScreenWidth;
/**
* The height of the physical output.
*/
uint _outputScreenHeight;
/**
* @return The desired aspect of the game screen.
*/
frac_t getDesiredGameScreenAspect() const;
/**
* Recalculates the area used to display the game screen.
*/
void recalculateDisplayArea();
/**
* The X coordinate of the game screen.
*/
uint _displayX;
/**
* The Y coordinate of the game screen.
*/
uint _displayY;
/**
* The width of the game screen in physical coordinates.
*/
uint _displayWidth;
/**
* The height of the game screen in physical coordinates.
*/
uint _displayHeight;
virtual bool gameNeedsAspectRatioCorrection() const override;
virtual void recalculateDisplayAreas() override;
virtual void handleResizeImpl(const int width, const int height) override;
/**
* The default pixel format of the backend.
@ -396,12 +313,8 @@ private:
*/
Graphics::PixelFormat _defaultFormatAlpha;
//
// Game screen
//
/**
* The virtual game screen.
* The rendering surface for the virtual game screen.
*/
Surface *_gameScreen;
@ -420,15 +333,10 @@ private:
//
/**
* The overlay screen.
* The rendering surface for the overlay.
*/
Surface *_overlay;
/**
* Whether the overlay is visible or not.
*/
bool _overlayVisible;
//
// Cursor
//
@ -439,37 +347,17 @@ private:
void updateCursorPalette();
/**
* The cursor image.
* The rendering surface for the mouse cursor.
*/
Surface *_cursor;
/**
* X coordinate of the cursor in phyiscal coordinates.
*/
int _cursorX;
/**
* Y coordinate of the cursor in physical coordinates.
*/
int _cursorY;
/**
* X coordinate used for drawing the cursor.
*/
int _cursorDisplayX;
/**
* Y coordinate used for drawing the cursor.
*/
int _cursorDisplayY;
/**
* The X offset for the cursor hotspot in unscaled coordinates.
* The X offset for the cursor hotspot in unscaled game coordinates.
*/
int _cursorHotspotX;
/**
* The Y offset for the cursor hotspot in unscaled coordinates.
* The Y offset for the cursor hotspot in unscaled game coordinates.
*/
int _cursorHotspotY;
@ -480,22 +368,24 @@ private:
void recalculateCursorScaling();
/**
* The X offset for the cursor hotspot in scaled coordinates.
* The X offset for the cursor hotspot in scaled game display area
* coordinates.
*/
int _cursorHotspotXScaled;
/**
* The Y offset for the cursor hotspot in scaled coordinates.
* The Y offset for the cursor hotspot in scaled game display area
* coordinates.
*/
int _cursorHotspotYScaled;
/**
* The width of the cursor scaled coordinates.
* The width of the cursor in scaled game display area coordinates.
*/
uint _cursorWidthScaled;
/**
* The height of the cursor scaled coordinates.
* The height of the cursor in scaled game display area coordinates.
*/
uint _cursorHeightScaled;
@ -504,11 +394,6 @@ private:
*/
uint32 _cursorKeyColor;
/**
* Whether the cursor is actually visible.
*/
bool _cursorVisible;
/**
* Whether no cursor scaling should be applied.
*/
@ -524,15 +409,6 @@ private:
*/
byte _cursorPalette[3 * 256];
//
// Misc
//
/**
* Whether the screen contents shall be forced to redrawn.
*/
bool _forceRedraw;
#ifdef USE_OSD
//
// OSD
@ -541,7 +417,7 @@ protected:
/**
* Returns the font used for on screen display
*/
virtual const Graphics::Font *getFontOSD();
virtual const Graphics::Font *getFontOSD() const;
private:
/**

View File

@ -21,8 +21,10 @@
*/
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
#include "backends/graphics/opengl/texture.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/platform/sdl/sdl.h"
#include "graphics/scaler/aspect.h"
#include "common/textconsole.h"
#include "common/config-manager.h"
@ -35,7 +37,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
#if SDL_VERSION_ATLEAST(2, 0, 0)
_glContext(),
#else
_lastVideoModeLoad(0), _hwScreen(nullptr),
_lastVideoModeLoad(0),
#endif
_graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
_desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
@ -46,20 +48,22 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Setup proper SDL OpenGL context creation.
// Set up proper SDL OpenGL context creation.
#if SDL_VERSION_ATLEAST(2, 0, 0)
OpenGL::ContextType glContextType;
// Context version 1.4 is choosen arbitrarily based on what most shader
// extensions were written against.
#define DEFAULT_GL_MAJOR 1
#define DEFAULT_GL_MINOR 4
enum {
DEFAULT_GL_MAJOR = 1,
DEFAULT_GL_MINOR = 4,
#define DEFAULT_GLES_MAJOR 1
#define DEFAULT_GLES_MINOR 1
DEFAULT_GLES_MAJOR = 1,
DEFAULT_GLES_MINOR = 1,
#define DEFAULT_GLES2_MAJOR 2
#define DEFAULT_GLES2_MINOR 0
DEFAULT_GLES2_MAJOR = 2,
DEFAULT_GLES2_MINOR = 0
};
#if USE_FORCED_GL
glContextType = OpenGL::kContextGL;
@ -127,12 +131,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
} else {
glContextType = OpenGL::kContextGL;
}
#undef DEFAULT_GL_MAJOR
#undef DEFAULT_GL_MINOR
#undef DEFAULT_GLES_MAJOR
#undef DEFAULT_GLES_MINOR
#undef DEFAULT_GLES2_MAJOR
#undef DEFAULT_GLES2_MINOR
#endif
setContextType(glContextType);
@ -217,7 +215,7 @@ void OpenGLSdlGraphicsManager::deactivateManager() {
SdlGraphicsManager::deactivateManager();
}
bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) {
bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
case OSystem::kFeatureIconifyWindow:
@ -246,7 +244,7 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
}
}
bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
#if SDL_VERSION_ATLEAST(2, 0, 0)
@ -344,7 +342,7 @@ void OpenGLSdlGraphicsManager::updateScreen() {
void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
void OpenGLSdlGraphicsManager::notifyResize(const int width, const int height) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
// We sometime get outdated resize events from SDL2. So check that the size we get
// is the actual current window size. If not ignore the resize.
@ -354,11 +352,10 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
// causes a SDL_WINDOWEVENT_RESIZED event with the old resolution to be sent, and this
// event is processed after recreating the window at the new resolution.
int currentWidth, currentHeight;
getWindowDimensions(&currentWidth, &currentHeight);
if (width != (uint)currentWidth || height != (uint)currentHeight)
getWindowSizeFromSdl(&currentWidth, &currentHeight);
if (width != currentWidth || height != currentHeight)
return;
setActualScreenSize(width, height);
_eventSource->resetKeyboardEmulation(width - 1, height - 1);
handleResize(width, height);
#else
if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) {
// We save that we handled a resize event here. We need to know this
@ -373,18 +370,6 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
#endif
}
void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
adjustMousePosition(point.x, point.y);
}
void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
setMousePosition(mouse.x, mouse.y);
}
void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
_window->warpMouseInWindow(x, y);
}
bool OpenGLSdlGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
// In some cases we might not want to load the requested video mode. This
// will assure that the window size is not altered.
@ -422,6 +407,11 @@ void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const {
return SDL_GL_GetProcAddress(name);
}
void OpenGLSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
OpenGLGraphicsManager::handleResizeImpl(width, height);
SdlGraphicsManager::handleResizeImpl(width, height);
}
bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
// In case we request a fullscreen mode we will use the mode the user
// has chosen last time or the biggest mode available.
@ -517,9 +507,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
notifyContextCreate(rgba8888, rgba8888);
int actualWidth, actualHeight;
getWindowDimensions(&actualWidth, &actualHeight);
setActualScreenSize(actualWidth, actualHeight);
_eventSource->resetKeyboardEmulation(actualWidth - 1, actualHeight - 1);
getWindowSizeFromSdl(&actualWidth, &actualHeight);
handleResize(actualWidth, actualHeight);
return true;
#else
// WORKAROUND: Working around infamous SDL bugs when switching
@ -566,8 +555,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
if (_hwScreen) {
notifyContextCreate(rgba8888, rgba8888);
setActualScreenSize(_hwScreen->w, _hwScreen->h);
_eventSource->resetKeyboardEmulation(_hwScreen->w - 1, _hwScreen->h - 1);
handleResize(_hwScreen->w, _hwScreen->h);
}
// Ignore resize events (from SDL) for a few frames, if this isn't
@ -580,20 +568,6 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
#endif
}
void OpenGLSdlGraphicsManager::getWindowDimensions(int *width, int *height) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GetWindowSize(_window->getSDLWindow(), width, height);
#else
if (width) {
*width = _hwScreen->w;
}
if (height) {
*height = _hwScreen->h;
}
#endif
}
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
switch (event.type) {
case Common::EVENT_KEYUP:
@ -707,7 +681,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
// current scale setting in case the user resized the
// window. Then we apply the direction change.
int windowWidth = 0, windowHeight = 0;
getWindowDimensions(&windowWidth, &windowHeight);
getWindowSizeFromSdl(&windowWidth, &windowHeight);
_graphicsScale = MAX<int>(windowWidth / _lastRequestedWidth, windowHeight / _lastRequestedHeight);
_graphicsScale = MAX<int>(_graphicsScale + direction, 1);
@ -725,7 +699,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
#ifdef USE_OSD
int windowWidth = 0, windowHeight = 0;
getWindowDimensions(&windowWidth, &windowHeight);
getWindowSizeFromSdl(&windowWidth, &windowHeight);
const Common::String osdMsg = Common::String::format(_("Resolution: %dx%d"), windowWidth, windowHeight);
displayMessageOnOSD(osdMsg.c_str());
#endif
@ -785,7 +759,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
}
bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) const {
if (event.kbd.hasFlags(Common::KBD_ALT)) {
return event.kbd.keycode == Common::KEYCODE_RETURN
|| event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER

View File

@ -36,38 +36,37 @@ public:
virtual ~OpenGLSdlGraphicsManager();
// GraphicsManager API
virtual void activateManager();
virtual void deactivateManager();
virtual void activateManager() override;
virtual void deactivateManager() override;
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
virtual bool hasFeature(OSystem::Feature f) const override;
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
virtual bool getFeatureState(OSystem::Feature f) const override;
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
#ifdef USE_RGB_COLOR
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
virtual void updateScreen();
virtual void updateScreen() override;
// EventObserver API
virtual bool notifyEvent(const Common::Event &event);
virtual bool notifyEvent(const Common::Event &event) override;
// SdlGraphicsManager API
virtual void notifyVideoExpose();
virtual void notifyResize(const uint width, const uint height);
virtual void transformMouseCoordinates(Common::Point &point);
virtual void notifyMousePos(Common::Point mouse);
virtual void notifyVideoExpose() override;
virtual void notifyResize(const int width, const int height) override;
protected:
virtual void setInternalMousePosition(int x, int y);
virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
virtual void refreshScreen() override;
virtual void refreshScreen();
virtual void *getProcAddress(const char *name) const override;
virtual void handleResizeImpl(const int width, const int height) override;
virtual void *getProcAddress(const char *name) const;
virtual int getGraphicsModeScale(int mode) const override { return 1; }
private:
@ -78,11 +77,8 @@ private:
SDL_GLContext _glContext;
#else
uint32 _lastVideoModeLoad;
SDL_Surface *_hwScreen;
#endif
void getWindowDimensions(int *width, int *height);
uint _lastRequestedWidth;
uint _lastRequestedHeight;
uint _graphicsScale;
@ -122,7 +118,7 @@ private:
uint _desiredFullscreenWidth;
uint _desiredFullscreenHeight;
virtual bool isHotkey(const Common::Event &event);
bool isHotkey(const Common::Event &event) const;
};
#endif

View File

@ -34,8 +34,8 @@ class OPGraphicsManager : public SurfaceSdlGraphicsManager {
public:
OPGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
bool loadGFXMode();
void unloadGFXMode();
bool loadGFXMode() override;
void unloadGFXMode() override;
};
#endif /* BACKENDS_GRAPHICS_OP_H */

View File

@ -30,19 +30,19 @@ class PSP2SdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
PSP2SdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual ~PSP2SdlGraphicsManager();
virtual OSystem::TransactionError endGFXTransaction();
virtual const OSystem::GraphicsMode *getSupportedShaders() const;
virtual OSystem::TransactionError endGFXTransaction() override;
virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
protected:
virtual void setGraphicsModeIntern();
virtual void unloadGFXMode();
virtual bool hotswapGFXMode();
virtual void setGraphicsModeIntern() override;
virtual void unloadGFXMode() override;
virtual bool hotswapGFXMode() override;
virtual void internUpdateScreen();
virtual void updateShader();
virtual void setAspectRatioCorrection(bool enable);
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
virtual void internUpdateScreen() override;
virtual void updateShader() override;
virtual void setAspectRatioCorrection(bool enable) override;
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) override;
void PSP2_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
void PSP2_UpdateFiltering();

View File

@ -32,7 +32,7 @@ SamsungTVSdlGraphicsManager::SamsungTVSdlGraphicsManager(SdlEventSource *sdlEven
: SurfaceSdlGraphicsManager(sdlEventSource, window) {
}
bool SamsungTVSdlGraphicsManager::hasFeature(OSystem::Feature f) {
bool SamsungTVSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
return
(f == OSystem::kFeatureAspectRatioCorrection) ||
(f == OSystem::kFeatureCursorPalette);
@ -48,7 +48,7 @@ void SamsungTVSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enabl
}
}
bool SamsungTVSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
bool SamsungTVSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureAspectRatioCorrection:
return SurfaceSdlGraphicsManager::getFeatureState(f);

View File

@ -31,9 +31,9 @@ class SamsungTVSdlGraphicsManager : public SurfaceSdlGraphicsManager {
public:
SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
bool hasFeature(OSystem::Feature f);
void setFeatureState(OSystem::Feature f, bool enable);
bool getFeatureState(OSystem::Feature f);
bool hasFeature(OSystem::Feature f) const override;
void setFeatureState(OSystem::Feature f, bool enable) override;
bool getFeatureState(OSystem::Feature f) const override;
};
#endif

View File

@ -28,15 +28,11 @@
#include "graphics/scaler/aspect.h"
SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
: _eventSource(source), _window(window)
: _eventSource(source), _window(window), _hwScreen(nullptr)
#if SDL_VERSION_ATLEAST(2, 0, 0)
, _allowWindowSizeReset(false), _hintedWidth(0), _hintedHeight(0), _lastFlags(0)
#endif
{
}
SdlGraphicsManager::~SdlGraphicsManager() {
}
{}
void SdlGraphicsManager::activateManager() {
_eventSource->setGraphicsManager(this);
@ -46,7 +42,7 @@ void SdlGraphicsManager::deactivateManager() {
_eventSource->setGraphicsManager(0);
}
SdlGraphicsManager::State SdlGraphicsManager::getState() {
SdlGraphicsManager::State SdlGraphicsManager::getState() const {
State state;
state.screenWidth = getWidth();
@ -152,6 +148,82 @@ void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) {
#endif
}
bool SdlGraphicsManager::showMouse(const bool visible) {
if (visible == _cursorVisible) {
return visible;
}
int showCursor = SDL_DISABLE;
if (visible) {
// _cursorX and _cursorY are currently always clipped to the active
// area, so we need to ask SDL where the system's mouse cursor is
// instead
int x, y;
SDL_GetMouseState(&x, &y);
if (!_activeArea.drawRect.contains(Common::Point(x, y))) {
showCursor = SDL_ENABLE;
}
}
SDL_ShowCursor(showCursor);
return WindowedGraphicsManager::showMouse(visible);
}
bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
int showCursor = SDL_DISABLE;
bool valid = true;
if (_activeArea.drawRect.contains(mouse)) {
_cursorLastInActiveArea = true;
} else {
mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
if (_window->mouseIsGrabbed() ||
// Keep the mouse inside the game area during dragging to prevent an
// event mismatch where the mouseup event gets lost because it is
// performed outside of the game area
(_cursorLastInActiveArea && SDL_GetMouseState(nullptr, nullptr) != 0)) {
setSystemMousePosition(mouse.x, mouse.y);
} else {
// Allow the in-game mouse to get a final movement event to the edge
// of the window if the mouse was moved out of the game area
if (_cursorLastInActiveArea) {
_cursorLastInActiveArea = false;
} else if (_cursorVisible) {
// Keep sending events to the game if the cursor is invisible,
// since otherwise if a game lets you skip a cutscene by
// clicking and the user moved the mouse outside the active
// area, the clicks wouldn't do anything, which would be
// confusing
valid = false;
}
if (_cursorVisible) {
showCursor = SDL_ENABLE;
}
}
}
SDL_ShowCursor(showCursor);
if (valid) {
setMousePosition(mouse.x, mouse.y);
mouse = convertWindowToVirtual(mouse.x, mouse.y);
}
return valid;
}
void SdlGraphicsManager::setSystemMousePosition(const int x, const int y) {
assert(_window);
if (!_window->warpMouseInWindow(x, y)) {
_eventSource->fakeWarpMouse(x, y);
}
}
void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
_eventSource->resetKeyboardEmulation(width - 1, height - 1);
_forceRedraw = true;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint32 flags) {
if (!_window) {
@ -159,11 +231,12 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3
}
// We only update the actual window when flags change (which usually means
// fullscreen mode is entered/exited) or when updates are forced so that we
// fullscreen mode is entered/exited), when updates are forced so that we
// do not reset the window size whenever a game makes a call to change the
// size or pixel format of the internal game surface (since a user may have
// resized the game window)
if (!_window->getSDLWindow() || _lastFlags != flags || _allowWindowSizeReset) {
// resized the game window), or when the launcher is visible (since a user
// may change the scaler, which should reset the window size)
if (!_window->getSDLWindow() || _lastFlags != flags || _overlayVisible || _allowWindowSizeReset) {
if (_hintedWidth) {
width = _hintedWidth;
}

View File

@ -23,7 +23,7 @@
#ifndef BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
#define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
#include "backends/graphics/graphics.h"
#include "backends/graphics/windowed.h"
#include "backends/platform/sdl/sdl-window.h"
#include "common/rect.h"
@ -32,13 +32,11 @@ class SdlEventSource;
/**
* Base class for a SDL based graphics manager.
*
* It features a few extra a few extra features required by SdlEventSource.
*/
class SdlGraphicsManager : virtual public GraphicsManager {
class SdlGraphicsManager : virtual public WindowedGraphicsManager {
public:
SdlGraphicsManager(SdlEventSource *source, SdlWindow *window);
virtual ~SdlGraphicsManager();
virtual ~SdlGraphicsManager() {}
/**
* Makes this graphics manager active. That means it should be ready to
@ -62,10 +60,10 @@ public:
virtual void notifyVideoExpose() = 0;
/**
* Notify the graphics manager about an resize event.
* Notify the graphics manager about a resize event.
*
* It is noteworthy that the requested width/height should actually be set
* up as is and not changed by the graphics manager, since else it might
* up as is and not changed by the graphics manager, since otherwise it may
* lead to odd behavior for certain window managers.
*
* It is only required to overwrite this method in case you want a
@ -74,27 +72,28 @@ public:
* @param width Requested window width.
* @param height Requested window height.
*/
virtual void notifyResize(const uint width, const uint height) {}
virtual void notifyResize(const int width, const int height) {}
/**
* Transforms real screen coordinates into the current active screen
* coordinates (may be either game screen or overlay).
* Notifies the graphics manager about a mouse position change.
*
* @param point Mouse coordinates to transform.
* The passed point *must* be converted from window coordinates to virtual
* coordinates in order for the event to be processed correctly by the game
* engine. Just use `convertWindowToVirtual` for this unless you need to do
* something special.
*
* @param mouse The mouse position in window coordinates, which must be
* converted synchronously to virtual coordinates.
* @returns true if the mouse was in a valid position for the game and
* should cause the event to be sent to the game.
*/
virtual void transformMouseCoordinates(Common::Point &point) = 0;
virtual bool notifyMousePosition(Common::Point &mouse);
/**
* Notifies the graphics manager about a position change according to the
* real screen coordinates.
*
* @param mouse Mouse position.
*/
virtual void notifyMousePos(Common::Point mouse) = 0;
virtual bool showMouse(const bool visible) override;
/**
* A (subset) of the graphic manager's state. This is used when switching
* between different SDL graphic managers on runtime.
* between different SDL graphic managers at runtime.
*/
struct State {
int screenWidth, screenHeight;
@ -108,17 +107,17 @@ public:
};
/**
* Queries the current state of the graphic manager.
* Gets the current state of the graphics manager.
*/
State getState();
State getState() const;
/**
* Setup a basic state of the graphic manager.
* Sets up a basic state of the graphics manager.
*/
bool setState(const State &state);
/**
* Queries the SDL window.
* @returns the SDL window.
*/
SdlWindow *getWindow() const { return _window; }
@ -130,6 +129,31 @@ protected:
bool defaultGraphicsModeConfig() const;
int getGraphicsModeIdByName(const Common::String &name) const;
/**
* Gets the dimensions of the window directly from SDL instead of from the
* values stored by the graphics manager.
*/
void getWindowSizeFromSdl(int *width, int *height) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
assert(_window);
SDL_GetWindowSize(_window->getSDLWindow(), width, height);
#else
assert(_hwScreen);
if (width) {
*width = _hwScreen->w;
}
if (height) {
*height = _hwScreen->h;
}
#endif
}
virtual void setSystemMousePosition(const int x, const int y) override;
virtual void handleResizeImpl(const int width, const int height) override;
#if SDL_VERSION_ATLEAST(2, 0, 0)
public:
void unlockWindowSize() {
@ -146,6 +170,7 @@ protected:
bool createOrUpdateWindow(const int width, const int height, const Uint32 flags);
#endif
SDL_Surface *_hwScreen;
SdlEventSource *_eventSource;
SdlWindow *_window;
};

File diff suppressed because it is too large Load Diff

View File

@ -39,17 +39,7 @@
#define USE_SDL_DEBUG_FOCUSRECT
#endif
// We have (some) support for resizable windows when SDL2 is used. However
// the overlay still uses the resolution setup with SDL_SetVideoMode. This
// makes the GUI look subpar when the user resizes the window. In addition
// we do not adapt the scale factor right now. Thus, we disable this code
// path for now.
#if SDL_VERSION_ATLEAST(2, 0, 0) && 0
#define USE_SDL_RESIZABLE_WINDOW
#endif
#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
// Uncomment this to enable the 'on screen display' code.
#define USE_OSD 1
#endif
@ -89,76 +79,70 @@ public:
SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
virtual ~SurfaceSdlGraphicsManager();
virtual void activateManager();
virtual void deactivateManager();
virtual void activateManager() override;
virtual void deactivateManager() override;
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
virtual bool hasFeature(OSystem::Feature f) const override;
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
virtual bool getFeatureState(OSystem::Feature f) const override;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
virtual void resetGraphicsScale();
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
virtual int getDefaultGraphicsMode() const override;
virtual bool setGraphicsMode(int mode) override;
virtual int getGraphicsMode() const override;
virtual void resetGraphicsScale() override;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
virtual Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
virtual const OSystem::GraphicsMode *getSupportedShaders() const;
virtual int getShader() const;
virtual bool setShader(int id);
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
virtual int getScreenChangeID() const { return _screenChangeCount; }
virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
virtual int getShader() const override;
virtual bool setShader(int id) override;
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
virtual int getScreenChangeID() const override { return _screenChangeCount; }
virtual void beginGFXTransaction();
virtual OSystem::TransactionError endGFXTransaction();
virtual void beginGFXTransaction() override;
virtual OSystem::TransactionError endGFXTransaction() override;
virtual int16 getHeight();
virtual int16 getWidth();
virtual int16 getHeight() const override;
virtual int16 getWidth() const override;
protected:
// PaletteManager API
virtual void setPalette(const byte *colors, uint start, uint num);
virtual void grabPalette(byte *colors, uint start, uint num);
virtual void setPalette(const byte *colors, uint start, uint num) override;
virtual void grabPalette(byte *colors, uint start, uint num) const override;
public:
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
virtual Graphics::Surface *lockScreen();
virtual void unlockScreen();
virtual void fillScreen(uint32 col);
virtual void updateScreen();
virtual void setShakePos(int shakeOffset);
virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle();
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
virtual Graphics::Surface *lockScreen() override;
virtual void unlockScreen() override;
virtual void fillScreen(uint32 col) override;
virtual void updateScreen() override;
virtual void setShakePos(int shakeOffset) override;
virtual void setFocusRectangle(const Common::Rect& rect) override;
virtual void clearFocusRectangle() override;
virtual void showOverlay();
virtual void hideOverlay();
virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
virtual void clearOverlay();
virtual void grabOverlay(void *buf, int pitch);
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
virtual int16 getOverlayHeight() { return _videoMode.overlayHeight; }
virtual int16 getOverlayWidth() { return _videoMode.overlayWidth; }
virtual Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
virtual void clearOverlay() override;
virtual void grabOverlay(void *buf, int pitch) const override;
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
virtual int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
virtual int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override;
virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
#ifdef USE_OSD
virtual void displayMessageOnOSD(const char *msg);
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
virtual void displayMessageOnOSD(const char *msg) override;
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
#endif
// Override from Common::EventObserver
bool notifyEvent(const Common::Event &event);
virtual bool notifyEvent(const Common::Event &event) override;
// SdlGraphicsManager interface
virtual void notifyVideoExpose();
virtual void notifyResize(const uint width, const uint height);
virtual void transformMouseCoordinates(Common::Point &point);
virtual void notifyMousePos(Common::Point mouse);
virtual void notifyVideoExpose() override;
virtual void notifyResize(const int width, const int height) override;
protected:
#ifdef USE_OSD
@ -187,8 +171,11 @@ protected:
void drawOSD();
#endif
/** Hardware screen */
SDL_Surface *_hwscreen;
virtual bool gameNeedsAspectRatioCorrection() const override {
return _videoMode.aspectRatioCorrection;
}
virtual void handleResizeImpl(const int width, const int height) override;
virtual int getGraphicsModeScale(int mode) const override;
@ -197,10 +184,7 @@ protected:
* around this API to keep the code paths as close as possible. */
SDL_Renderer *_renderer;
SDL_Texture *_screenTexture;
SDL_Rect _viewport;
int _windowWidth, _windowHeight;
void deinitializeRenderer();
void setWindowResolution(int width, int height);
void recreateScreenTexture();
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
@ -209,9 +193,9 @@ protected:
/** Unseen game screen */
SDL_Surface *_screen;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat _screenFormat;
Graphics::PixelFormat _cursorFormat;
#ifdef USE_RGB_COLOR
Common::List<Graphics::PixelFormat> _supportedFormats;
/**
@ -227,7 +211,6 @@ protected:
SDL_Surface *_tmpscreen2;
SDL_Surface *_overlayscreen;
bool _overlayVisible;
Graphics::PixelFormat _overlayFormat;
enum {
@ -289,14 +272,11 @@ protected:
uint8 _originalBitsPerPixel;
#endif
/** Force full redraw on next updateScreen */
bool _forceFull;
ScalerProc *_scalerProc;
int _scalerType;
int _transactionMode;
// Indicates whether it is needed to free _hwsurface in destructor
// Indicates whether it is needed to free _hwSurface in destructor
bool _displayDisabled;
bool _screenIsLocked;
@ -317,10 +297,6 @@ protected:
int _numDirtyRects;
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;
@ -335,14 +311,12 @@ protected:
int16 vW, vH;
int16 vHotX, vHotY;
MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
MousePos() : w(0), h(0), hotX(0), hotY(0),
rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
vHotX(0), vHotY(0)
{ }
};
bool _mouseVisible;
bool _mouseNeedsRedraw;
byte *_mouseData;
SDL_Rect _mouseBackup;
MousePos _mouseCurState;
@ -395,21 +369,45 @@ protected:
virtual void unloadGFXMode();
virtual bool hotswapGFXMode();
virtual void setFullscreenMode(bool enable);
virtual void setAspectRatioCorrection(bool enable);
#if SDL_VERSION_ATLEAST(2, 0, 0)
virtual void setFilteringMode(bool enable);
void setFilteringMode(bool enable);
#endif
virtual int effectiveScreenHeight() const;
virtual bool saveScreenshot(const char *filename);
virtual void setGraphicsModeIntern();
virtual bool handleScalerHotkeys(Common::KeyCode key);
virtual bool isScalerHotkey(const Common::Event &event);
virtual void setMousePos(int x, int y);
virtual void toggleFullScreen();
virtual bool saveScreenshot(const char *filename);
private:
void setFullscreenMode(bool enable);
bool handleScalerHotkeys(Common::KeyCode key);
bool isScalerHotkey(const Common::Event &event);
void toggleFullScreen();
/**
* Converts the given point from the overlay's coordinate space to the
* game's coordinate space.
*/
Common::Point convertOverlayToGame(const int x, const int y) const {
if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
error("convertOverlayToGame called without a valid overlay");
}
return Common::Point(x * getWidth() / getOverlayWidth(),
y * getHeight() / getOverlayHeight());
}
/**
* Converts the given point from the game's coordinate space to the
* overlay's coordinate space.
*/
Common::Point convertGameToOverlay(const int x, const int y) const {
if (getWidth() == 0 || getHeight() == 0) {
error("convertGameToOverlay called without a valid overlay");
}
return Common::Point(x * getOverlayWidth() / getWidth(),
y * getOverlayHeight() / getHeight());
}
};
#endif

View File

@ -50,7 +50,7 @@ bool SymbianSdlGraphicsManager::setGraphicsMode(int /*name*/) {
return SurfaceSdlGraphicsManager::setGraphicsMode(getDefaultGraphicsMode());
}
bool SymbianSdlGraphicsManager::hasFeature(OSystem::Feature f) {
bool SymbianSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
case OSystem::kFeatureAspectRatioCorrection:

View File

@ -30,12 +30,12 @@ public:
SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
public:
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool hasFeature(OSystem::Feature f) const override;
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
virtual int getDefaultGraphicsMode() const override;
virtual bool setGraphicsMode(int mode) override;
};
#endif

View File

@ -115,7 +115,7 @@ const OSystem::GraphicsMode *WINCESdlGraphicsManager::getSupportedGraphicsModes(
return s_supportedGraphicsModesLow;
}
bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) {
bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) const {
return (f == OSystem::kFeatureVirtualKeyboard);
}
@ -153,7 +153,7 @@ void WINCESdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
}
bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) {
bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
return false;

View File

@ -46,9 +46,9 @@ public:
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
bool hasFeature(OSystem::Feature f);
bool hasFeature(OSystem::Feature f) const;
void setFeatureState(OSystem::Feature f, bool enable);
bool getFeatureState(OSystem::Feature f);
bool getFeatureState(OSystem::Feature f) const;
int getDefaultGraphicsMode() const;
bool setGraphicsMode(int mode);

View File

@ -0,0 +1,337 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef BACKENDS_GRAPHICS_WINDOWED_H
#define BACKENDS_GRAPHICS_WINDOWED_H
#include "backends/graphics/graphics.h"
#include "common/frac.h"
#include "common/rect.h"
#include "common/textconsole.h"
#include "graphics/scaler/aspect.h"
class WindowedGraphicsManager : virtual public GraphicsManager {
public:
WindowedGraphicsManager() :
_windowWidth(0),
_windowHeight(0),
_overlayVisible(false),
_forceRedraw(false),
_cursorVisible(false),
_cursorX(0),
_cursorY(0),
_cursorNeedsRedraw(false),
_cursorLastInActiveArea(true) {}
virtual void showOverlay() override {
if (_overlayVisible)
return;
_activeArea.drawRect = _overlayDrawRect;
_activeArea.width = getOverlayWidth();
_activeArea.height = getOverlayHeight();
_overlayVisible = true;
_forceRedraw = true;
}
virtual void hideOverlay() override {
if (!_overlayVisible)
return;
_activeArea.drawRect = _gameDrawRect;
_activeArea.width = getWidth();
_activeArea.height = getHeight();
_overlayVisible = false;
_forceRedraw = true;
}
protected:
/**
* @returns whether or not the game screen must have aspect ratio correction
* applied for correct rendering.
*/
virtual bool gameNeedsAspectRatioCorrection() const = 0;
/**
* Backend-specific implementation for updating internal surfaces that need
* to reflect the new window size.
*/
virtual void handleResizeImpl(const int width, const int height) = 0;
/**
* Converts the given point from the active virtual screen's coordinate
* space to the window's coordinate space (i.e. game-to-window or
* overlay-to-window).
*/
Common::Point convertVirtualToWindow(const int x, const int y) const {
const int targetX = _activeArea.drawRect.left;
const int targetY = _activeArea.drawRect.top;
const int targetWidth = _activeArea.drawRect.width();
const int targetHeight = _activeArea.drawRect.height();
const int sourceWidth = _activeArea.width;
const int sourceHeight = _activeArea.height;
if (sourceWidth == 0 || sourceHeight == 0) {
error("convertVirtualToWindow called without a valid draw rect");
}
return Common::Point(targetX + x * targetWidth / sourceWidth,
targetY + y * targetHeight / sourceHeight);
}
/**
* Converts the given point from the window's coordinate space to the
* active virtual screen's coordinate space (i.e. window-to-game or
* window-to-overlay).
*/
Common::Point convertWindowToVirtual(int x, int y) const {
const int sourceX = _activeArea.drawRect.left;
const int sourceY = _activeArea.drawRect.top;
const int sourceMaxX = _activeArea.drawRect.right - 1;
const int sourceMaxY = _activeArea.drawRect.bottom - 1;
const int sourceWidth = _activeArea.drawRect.width();
const int sourceHeight = _activeArea.drawRect.height();
const int targetWidth = _activeArea.width;
const int targetHeight = _activeArea.height;
if (sourceWidth == 0 || sourceHeight == 0) {
error("convertWindowToVirtual called without a valid draw rect");
}
x = CLIP<int>(x, sourceX, sourceMaxX);
y = CLIP<int>(y, sourceY, sourceMaxY);
return Common::Point(((x - sourceX) * targetWidth) / sourceWidth,
((y - sourceY) * targetHeight) / sourceHeight);
}
/**
* @returns the desired aspect ratio of the game surface.
*/
frac_t getDesiredGameAspectRatio() const {
if (getHeight() == 0 || gameNeedsAspectRatioCorrection()) {
return intToFrac(4) / 3;
}
return intToFrac(getWidth()) / getHeight();
}
/**
* Called after the window has been updated with new dimensions.
*
* @param width The new width of the window, excluding window decoration.
* @param height The new height of the window, excluding window decoration.
*/
void handleResize(const int width, const int height) {
_windowWidth = width;
_windowHeight = height;
handleResizeImpl(width, height);
}
/**
* Recalculates the display areas for the game and overlay surfaces within
* the window.
*/
virtual void recalculateDisplayAreas() {
if (_windowHeight == 0) {
return;
}
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), outputAspect, _gameDrawRect);
if (getOverlayHeight()) {
const frac_t overlayAspect = intToFrac(getOverlayWidth()) / getOverlayHeight();
populateDisplayAreaDrawRect(overlayAspect, outputAspect, _overlayDrawRect);
}
if (_overlayVisible) {
_activeArea.drawRect = _overlayDrawRect;
_activeArea.width = getOverlayWidth();
_activeArea.height = getOverlayHeight();
} else {
_activeArea.drawRect = _gameDrawRect;
_activeArea.width = getWidth();
_activeArea.height = getHeight();
}
}
/**
* Sets the position of the hardware mouse cursor in the host system,
* relative to the window.
*
* @param x X coordinate in window coordinates.
* @param y Y coordinate in window coordinates.
*/
virtual void setSystemMousePosition(const int x, const int y) = 0;
virtual bool showMouse(const bool visible) override {
if (_cursorVisible == visible) {
return visible;
}
const bool last = _cursorVisible;
_cursorVisible = visible;
_cursorNeedsRedraw = true;
return last;
}
/**
* Move ("warp") the mouse cursor to the specified position.
*
* @param x The new X position of the mouse in virtual screen coordinates.
* @param y The new Y position of the mouse in virtual screen coordinates.
*/
void warpMouse(const int x, const int y) {
// Check active coordinate instead of window coordinate to avoid warping
// the mouse if it is still within the same virtual pixel
const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
if (virtualCursor.x != x || virtualCursor.y != y) {
// Warping the mouse in SDL generates a mouse movement event, so
// `setMousePosition` would be called eventually through the
// `notifyMousePosition` callback if we *only* set the system mouse
// position here. However, this can cause problems with some games.
// For example, the cannon script in CoMI calls to warp the mouse
// twice each time the cannon is reloaded, and unless we update the
// mouse position immediately, the second call is ignored, which
// causes the cannon to change its aim.
const Common::Point windowCursor = convertVirtualToWindow(x, y);
setMousePosition(windowCursor.x, windowCursor.y);
setSystemMousePosition(windowCursor.x, windowCursor.y);
}
}
/**
* Sets the position of the rendered mouse cursor in the window.
*
* @param x X coordinate in window coordinates.
* @param y Y coordinate in window coordinates.
*/
void setMousePosition(int x, int y) {
if (_cursorX != x || _cursorY != y) {
_cursorNeedsRedraw = true;
}
_cursorX = x;
_cursorY = y;
}
/**
* The width of the window, excluding window decoration.
*/
int _windowWidth;
/**
* The height of the window, excluding window decoration.
*/
int _windowHeight;
/**
* Whether the overlay (i.e. launcher, including the out-of-game launcher)
* is visible or not.
*/
bool _overlayVisible;
/**
* The scaled draw rectangle for the game surface within the window.
*/
Common::Rect _gameDrawRect;
/**
* The scaled draw rectangle for the overlay (launcher) surface within the
* window.
*/
Common::Rect _overlayDrawRect;
/**
* Data about the display area of a virtual screen.
*/
struct DisplayArea {
/**
* The scaled area where the virtual screen is drawn within the window.
*/
Common::Rect drawRect;
/**
* The width of the virtual screen's unscaled coordinate space.
*/
int width;
/**
* The height of the virtual screen's unscaled coordinate space.
*/
int height;
};
/**
* Display area information about the currently active virtual screen. This
* will be the overlay screen when the overlay is active, and the game
* screen otherwise.
*/
DisplayArea _activeArea;
/**
* Whether the screen must be redrawn on the next frame.
*/
bool _forceRedraw;
/**
* Whether the cursor is actually visible.
*/
bool _cursorVisible;
/**
* Whether the mouse cursor needs to be redrawn on the next frame.
*/
bool _cursorNeedsRedraw;
/**
* Whether the last position of the system cursor was within the active area
* of the window.
*/
bool _cursorLastInActiveArea;
/**
* The position of the mouse cursor, in window coordinates.
*/
int _cursorX, _cursorY;
private:
void populateDisplayAreaDrawRect(const frac_t inputAspect, const frac_t outputAspect, Common::Rect &drawRect) const {
int width = _windowWidth;
int height = _windowHeight;
// Maintain aspect ratios
if (outputAspect < inputAspect) {
height = intToFrac(width) / inputAspect;
} else if (outputAspect > inputAspect) {
width = fracToInt(height * inputAspect);
}
drawRect.left = (_windowWidth - width) / 2;
drawRect.top = (_windowHeight - height) / 2;
drawRect.setWidth(width);
drawRect.setHeight(height);
}
};
#endif

View File

@ -217,6 +217,7 @@ bool ModularBackend::showMouse(bool visible) {
}
void ModularBackend::warpMouse(int x, int y) {
_eventManager->purgeMouseEvents();
_graphicsManager->warpMouse(x, y);
}

View File

@ -135,8 +135,10 @@ void SdlWindow::toggleMouseGrab() {
#else
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
SDL_WM_GrabInput(SDL_GRAB_ON);
_inputGrabState = true;
} else {
SDL_WM_GrabInput(SDL_GRAB_OFF);
_inputGrabState = false;
}
#endif
}
@ -153,14 +155,20 @@ bool SdlWindow::hasMouseFocus() const {
#endif
}
void SdlWindow::warpMouseInWindow(uint x, uint y) {
bool SdlWindow::warpMouseInWindow(int x, int y) {
if (hasMouseFocus()) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (_window && hasMouseFocus()) {
SDL_WarpMouseInWindow(_window, x, y);
}
if (_window) {
SDL_WarpMouseInWindow(_window, x, y);
return true;
}
#else
SDL_WarpMouse(x, y);
SDL_WarpMouse(x, y);
return true;
#endif
}
return false;
}
void SdlWindow::iconifyWindow() {

View File

@ -56,9 +56,12 @@ public:
bool hasMouseFocus() const;
/**
* Warp the mouse to the specified position in window coordinates.
* Warp the mouse to the specified position in window coordinates. The mouse
* will only be warped if the window is focused in the window manager.
*
* @returns true if the system cursor was warped.
*/
void warpMouseInWindow(uint x, uint y);
bool warpMouseInWindow(int x, int y);
/**
* Iconifies the window.
@ -73,6 +76,11 @@ public:
*/
bool getSDLWMInformation(SDL_SysWMinfo *info) const;
bool mouseIsGrabbed() const { return _inputGrabState; }
private:
bool _inputGrabState;
#if SDL_VERSION_ATLEAST(2, 0, 0)
public:
/**
@ -108,7 +116,6 @@ private:
*/
int _lastX, _lastY;
bool _inputGrabState;
Common::String _windowCaption;
#endif
};

View File

@ -395,6 +395,11 @@ public:
*/
virtual void pushEvent(const Event &event) = 0;
/**
* Purges all unprocessed mouse events already in the event queue.
*/
virtual void purgeMouseEvents() = 0;
/** Return the current mouse position */
virtual Point getMousePos() const = 0;

View File

@ -65,9 +65,7 @@ void CursorManager::pushCursor(const void *buf, uint w, uint h, int hotspotX, in
cur->_visible = isVisible();
_cursorStack.push(cur);
if (buf) {
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
}
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
}
void CursorManager::popCursor() {
@ -80,6 +78,8 @@ void CursorManager::popCursor() {
if (!_cursorStack.empty()) {
cur = _cursorStack.top();
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format);
} else {
g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
}
g_system->showMouse(isVisible());
@ -99,6 +99,7 @@ void CursorManager::popAllCursors() {
}
}
g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
g_system->showMouse(isVisible());
}

View File

@ -96,7 +96,7 @@ public:
*
* @see getScreenFormat
*/
virtual void grabPalette(byte *colors, uint start, uint num) = 0;
virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
};
#endif