aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-10-15 13:26:39 -0500
committerColin Snover2017-10-15 13:26:39 -0500
commit7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc (patch)
treea35cf3cd386219e8c945ba8aacc3e20c442fbf69
parent7fc86195343adf962054fd52605c3a3cc8b501e9 (diff)
parent4757c24c683c2f2b8e3b55aa8d7a767aad9e947e (diff)
downloadscummvm-rg350-7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc.tar.gz
scummvm-rg350-7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc.tar.bz2
scummvm-rg350-7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc.zip
Merge branch 'graphics-backends-improvements'
-rw-r--r--backends/events/default/default-events.cpp26
-rw-r--r--backends/events/default/default-events.h1
-rw-r--r--backends/events/sdl/sdl-events.cpp56
-rw-r--r--backends/events/sdl/sdl-events.h20
-rw-r--r--backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp8
-rw-r--r--backends/graphics/dinguxsdl/dinguxsdl-graphics.h37
-rw-r--r--backends/graphics/gph/gph-graphics.cpp12
-rw-r--r--backends/graphics/gph/gph-graphics.h37
-rw-r--r--backends/graphics/graphics.h18
-rw-r--r--backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h24
-rw-r--r--backends/graphics/maemosdl/maemosdl-graphics.h2
-rw-r--r--backends/graphics/null/null-graphics.h76
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp248
-rw-r--r--backends/graphics/opengl/opengl-graphics.h234
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp84
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h36
-rw-r--r--backends/graphics/openpandora/op-graphics.h4
-rw-r--r--backends/graphics/psp2sdl/psp2sdl-graphics.h22
-rw-r--r--backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp4
-rw-r--r--backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h6
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp93
-rw-r--r--backends/graphics/sdl/sdl-graphics.h73
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp807
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h176
-rw-r--r--backends/graphics/symbiansdl/symbiansdl-graphics.cpp2
-rw-r--r--backends/graphics/symbiansdl/symbiansdl-graphics.h10
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.cpp4
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.h4
-rw-r--r--backends/graphics/windowed.h337
-rw-r--r--backends/modular-backend.cpp1
-rw-r--r--backends/platform/sdl/sdl-window.cpp18
-rw-r--r--backends/platform/sdl/sdl-window.h13
-rw-r--r--common/events.h5
-rw-r--r--graphics/cursorman.cpp7
-rw-r--r--graphics/palette.h2
35 files changed, 1284 insertions, 1223 deletions
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index c7c39da069..667914b023 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -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)
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index f378fb9ff0..38406c25aa 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -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; }
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index fb5a4c9b09..91ca0f5df6 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -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);
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index cf445e9e2c..5fd3cb7ea5 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -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.
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
index 10605f45a7..3de6439d1a 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
@@ -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) {
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
index 8a356106ad..89ee1411f1 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
@@ -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;
-
- 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();
+ 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) 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);
};
diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp
index 767fb57e11..e2c84114c4 100644
--- a/backends/graphics/gph/gph-graphics.cpp
+++ b/backends/graphics/gph/gph-graphics.cpp
@@ -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) {
diff --git a/backends/graphics/gph/gph-graphics.h b/backends/graphics/gph/gph-graphics.h
index 152d29ddf4..69e3b8947f 100644
--- a/backends/graphics/gph/gph-graphics.h
+++ b/backends/graphics/gph/gph-graphics.h
@@ -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;
-
- 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();
+ 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) 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);
};
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index bcd659ac11..cf33803cf5 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -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;
diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
index d7a13b1cb4..e7f96e877c 100644
--- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
+++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
@@ -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);
};
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.h b/backends/graphics/maemosdl/maemosdl-graphics.h
index 4cb84c81ee..ff4278b48c 100644
--- a/backends/graphics/maemosdl/maemosdl-graphics.h
+++ b/backends/graphics/maemosdl/maemosdl-graphics.h
@@ -32,7 +32,7 @@ public:
MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
protected:
- virtual bool loadGFXMode();
+ virtual bool loadGFXMode() override;
};
#endif
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index 67306c29f3..4c628568ff 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -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
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 28ca110d91..7bac4c85cb 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -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.
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index e02137bba7..df968aa67e 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -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:
/**
@@ -129,15 +124,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.
*
* This needs to be called at least once (and before ever calling
@@ -167,33 +153,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.
*
* @param format The pixel format the Surface object should accept as
@@ -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;
@@ -505,11 +395,6 @@ private:
uint32 _cursorKeyColor;
/**
- * Whether the cursor is actually visible.
- */
- bool _cursorVisible;
-
- /**
* Whether no cursor scaling should be applied.
*/
bool _cursorDontScale;
@@ -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:
/**
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 73fc87a75f..c77e9dafc5 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -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
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index c5003d867b..954c7215a4 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -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
diff --git a/backends/graphics/openpandora/op-graphics.h b/backends/graphics/openpandora/op-graphics.h
index 50994072bb..56777dc892 100644
--- a/backends/graphics/openpandora/op-graphics.h
+++ b/backends/graphics/openpandora/op-graphics.h
@@ -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 */
diff --git a/backends/graphics/psp2sdl/psp2sdl-graphics.h b/backends/graphics/psp2sdl/psp2sdl-graphics.h
index 638437c9a6..0cabeb094d 100644
--- a/backends/graphics/psp2sdl/psp2sdl-graphics.h
+++ b/backends/graphics/psp2sdl/psp2sdl-graphics.h
@@ -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 internUpdateScreen();
- virtual void updateShader();
- virtual void setAspectRatioCorrection(bool enable);
- virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+ virtual void setGraphicsModeIntern() override;
+ virtual void unloadGFXMode() override;
+ virtual bool hotswapGFXMode() override;
+
+ 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();
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
index 0c98462891..befa793263 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
@@ -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);
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
index 8699d77bc8..b86ebe2c45 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
@@ -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
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index a181582235..0e0a45a38f 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -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;
}
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 74ee2838ea..526306270b 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -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.
- */
- virtual void transformMouseCoordinates(Common::Point &point) = 0;
-
- /**
- * Notifies the graphics manager about a position change according to the
- * real screen coordinates.
+ * 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 Mouse position.
+ * @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 notifyMousePos(Common::Point mouse) = 0;
+ virtual bool notifyMousePosition(Common::Point &mouse);
+
+ 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;
};
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 897cdcb352..f025cfa7e5 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -23,7 +23,6 @@
#include "common/scummsys.h"
#if defined(SDL_BACKEND)
-
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
#include "backends/events/sdl/sdl-events.h"
#include "backends/platform/sdl/sdl.h"
@@ -133,24 +132,19 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_osdMessageSurface(nullptr), _osdMessageAlpha(SDL_ALPHA_TRANSPARENT), _osdMessageFadeStartTime(0),
_osdIconSurface(nullptr),
#endif
- _hwscreen(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
_renderer(nullptr), _screenTexture(nullptr),
- _viewport(), _windowWidth(1), _windowHeight(1),
#endif
#if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
_originalBitsPerPixel(0),
#endif
_screen(0), _tmpscreen(0),
-#ifdef USE_RGB_COLOR
_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
-#endif
- _overlayVisible(false),
_overlayscreen(0), _tmpscreen2(0),
_scalerProc(0), _screenChangeCount(0),
- _mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
- _mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
+ _mouseData(nullptr), _mouseSurface(nullptr),
+ _mouseOrigSurface(nullptr), _cursorDontScale(false), _cursorPaletteDisabled(true),
_currentShakePos(0), _newShakePos(0),
_paletteDirtyStart(0), _paletteDirtyEnd(0),
_screenIsLocked(false),
@@ -214,21 +208,19 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
unloadGFXMode();
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- if (_window)
- _window->destroyWindow();
-#endif
- if (_mouseSurface)
- SDL_FreeSurface(_mouseSurface);
- _mouseSurface = 0;
- if (_mouseOrigSurface)
+ if (_mouseOrigSurface) {
SDL_FreeSurface(_mouseOrigSurface);
- _mouseOrigSurface = 0;
+ if (_mouseOrigSurface == _mouseSurface) {
+ _mouseSurface = nullptr;
+ }
+ }
+ if (_mouseSurface) {
+ SDL_FreeSurface(_mouseSurface);
+ }
g_system->deleteMutex(_graphicsMutex);
-
free(_currentPalette);
free(_cursorPalette);
- free(_mouseData);
+ delete[] _mouseData;
}
void SurfaceSdlGraphicsManager::activateManager() {
@@ -247,7 +239,7 @@ void SurfaceSdlGraphicsManager::deactivateManager() {
SdlGraphicsManager::deactivateManager();
}
-bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
return
(f == OSystem::kFeatureFullscreenMode) ||
(f == OSystem::kFeatureAspectRatioCorrection) ||
@@ -284,7 +276,7 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
}
}
-bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
// We need to allow this to be called from within a transaction, since we
// currently use it to retreive the graphics state, when switching from
// SDL->OpenGL mode for example.
@@ -555,16 +547,16 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
};
- if (_hwscreen) {
+ if (_hwScreen) {
// Get our currently set hardware format
- Graphics::PixelFormat hwFormat(_hwscreen->format->BytesPerPixel,
- 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss,
- 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss,
- _hwscreen->format->Rshift, _hwscreen->format->Gshift,
- _hwscreen->format->Bshift, _hwscreen->format->Ashift);
+ Graphics::PixelFormat hwFormat(_hwScreen->format->BytesPerPixel,
+ 8 - _hwScreen->format->Rloss, 8 - _hwScreen->format->Gloss,
+ 8 - _hwScreen->format->Bloss, 8 - _hwScreen->format->Aloss,
+ _hwScreen->format->Rshift, _hwScreen->format->Gshift,
+ _hwScreen->format->Bshift, _hwScreen->format->Ashift);
// Workaround to SDL not providing an accurate Aloss value on Mac OS X.
- if (_hwscreen->format->Amask == 0)
+ if (_hwScreen->format->Amask == 0)
hwFormat.aLoss = 8;
_supportedFormats.push_back(hwFormat);
@@ -579,7 +571,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
// Push some RGB formats
for (i = 0; i < ARRAYSIZE(RGBList); i++) {
- if (_hwscreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
+ if (_hwScreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (RGBList[i] != format)
_supportedFormats.push_back(RGBList[i]);
@@ -587,7 +579,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
// Push some BGR formats
for (i = 0; i < ARRAYSIZE(BGRList); i++) {
- if (_hwscreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
+ if (_hwScreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (BGRList[i] != format)
_supportedFormats.push_back(BGRList[i]);
@@ -722,11 +714,11 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
}
}
- if (!_screen || !_hwscreen)
+ if (!_screen || !_hwScreen)
return;
// Blit everything to the screen
- _forceFull = true;
+ _forceRedraw = true;
// Even if the old and new scale factors are the same, we may have a
// different scaler for the cursor now.
@@ -797,13 +789,6 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo
_transactionDetails.sizeChanged = true;
}
-int SurfaceSdlGraphicsManager::effectiveScreenHeight() const {
- return _videoMode.scaleFactor *
- (_videoMode.aspectRatioCorrection
- ? real2Aspect(_videoMode.screenHeight)
- : _videoMode.screenHeight);
-}
-
static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) {
assert(&width != &height);
@@ -864,7 +849,7 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
}
bool SurfaceSdlGraphicsManager::loadGFXMode() {
- _forceFull = true;
+ _forceRedraw = true;
#if !defined(__MAEMO__) && !defined(DINGUX) && !defined(GPH_DEVICE) && !defined(LINUXMOTO) && !defined(OPENPANDORA)
_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
@@ -873,11 +858,14 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
_videoMode.aspectRatioCorrection = false;
- if (_videoMode.aspectRatioCorrection)
+ _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ _videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+
+ if (_videoMode.aspectRatioCorrection) {
_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
+ _videoMode.hardwareHeight = real2Aspect(_videoMode.hardwareHeight);
+ }
- _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
- _videoMode.hardwareHeight = effectiveScreenHeight();
// On GPH devices ALL the _videoMode.hardware... are setup in GPHGraphicsManager::loadGFXMode()
#elif !defined(GPH_DEVICE)
_videoMode.hardwareWidth = _videoMode.overlayWidth;
@@ -887,22 +875,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
//
// Create the surface that contains the 8 bit game data
//
-#ifdef USE_RGB_COLOR
+
+ const Graphics::PixelFormat &format = _screenFormat;
+ const Uint32 rMask = ((0xFF >> format.rLoss) << format.rShift);
+ const Uint32 gMask = ((0xFF >> format.gLoss) << format.gShift);
+ const Uint32 bMask = ((0xFF >> format.bLoss) << format.bShift);
+ const Uint32 aMask = ((0xFF >> format.aLoss) << format.aShift);
_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight,
- _screenFormat.bytesPerPixel << 3,
- ((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift ,
- ((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift ,
- ((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift ,
- ((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift );
+ _screenFormat.bytesPerPixel * 8, rMask, gMask, bMask, aMask);
if (_screen == NULL)
error("allocating _screen failed");
+#ifdef USE_RGB_COLOR
// Avoid having SDL_SRCALPHA set even if we supplied an alpha-channel in the format.
SDL_SetAlpha(_screen, 0, 255);
-#else
- _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
- if (_screen == NULL)
- error("allocating _screen failed");
#endif
// SDL 1.2 palettes default to all black,
@@ -924,7 +910,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_displayDisabled = ConfMan.getBool("disable_display");
if (_displayDisabled) {
- _hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+ _hwScreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
} else
#endif
{
@@ -937,7 +923,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
}
#endif
- _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
+ _hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
);
}
@@ -946,9 +932,9 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
detectSupportedFormats();
#endif
- if (_hwscreen == NULL) {
+ if (_hwScreen == NULL) {
// DON'T use error(), as this tries to bring up the debug
- // console, which WON'T WORK now that _hwscreen is hosed.
+ // console, which WON'T WORK now that _hwScreen is hosed.
if (!_oldVideoMode.setup) {
warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
@@ -958,6 +944,10 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
}
}
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+ handleResize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+#endif
+
//
// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
//
@@ -965,20 +955,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
// Need some extra bytes around when using 2xSaI
_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_tmpscreen == NULL)
error("allocating _tmpscreen failed");
_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_overlayscreen == NULL)
error("allocating _overlayscreen failed");
@@ -997,25 +987,16 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
if (_tmpscreen2 == NULL)
error("allocating _tmpscreen2 failed");
-#if !SDL_VERSION_ATLEAST(2, 0, 0)
- // For SDL2 the output resolution might differ from the requested
- // resolution. We handle resetting the keyboard emulation properly inside
- // our SDL_SetVideoMode wrapper for SDL2.
- _eventSource->resetKeyboardEmulation(
- _videoMode.screenWidth * _videoMode.scaleFactor - 1,
- effectiveScreenHeight() - 1);
-#endif
-
// Distinguish 555 and 565 mode
- if (_hwscreen->format->Rmask == 0x7C00)
+ if (_hwScreen->format->Rmask == 0x7C00)
InitScalers(555);
else
InitScalers(565);
@@ -1033,9 +1014,9 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
deinitializeRenderer();
#endif
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
+ if (_hwScreen) {
+ SDL_FreeSurface(_hwScreen);
+ _hwScreen = NULL;
}
if (_tmpscreen) {
@@ -1087,9 +1068,9 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
_overlayscreen = NULL;
// Release the HW screen surface
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
+ if (_hwScreen) {
+ SDL_FreeSurface(_hwScreen);
+ _hwScreen = NULL;
}
if (_tmpscreen) {
SDL_FreeSurface(_tmpscreen);
@@ -1139,14 +1120,14 @@ void SurfaceSdlGraphicsManager::updateScreen() {
}
void SurfaceSdlGraphicsManager::updateShader() {
-// shader init code goes here
-// currently only used on Vita port
-// the user-selected shaderID should be obtained via ConfMan.getInt("shader")
-// and the corresponding shader should then be activated here
-// this way the user can combine any software scaling (scalers)
-// with any hardware shading (shaders). The shaders could provide
-// scanline masks, overlays, but could also serve for
-// hardware-based up-scaling (sharp-bilinear-simple, etc.)
+ // shader init code goes here
+ // currently only used on Vita port
+ // the user-selected shaderID should be obtained via ConfMan.getInt("shader")
+ // and the corresponding shader should then be activated here
+ // this way the user can combine any software scaling (scalers)
+ // with any hardware shading (shaders). The shaders could provide
+ // scanline masks, overlays, but could also serve for
+ // hardware-based up-scaling (sharp-bilinear-simple, etc.)
}
void SurfaceSdlGraphicsManager::internUpdateScreen() {
@@ -1155,25 +1136,19 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
ScalerProc *scalerProc;
int scale1;
- // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
-#if defined(DEBUG) && !defined(WIN32) && !defined(_WIN32_WCE)
- assert(_hwscreen != NULL);
- assert(_hwscreen->map->sw_data != NULL);
-#endif
-
// If the shake position changed, fill the dirty area with blackness
if (_currentShakePos != _newShakePos ||
- (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+ (_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)};
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
blackrect.h = real2Aspect(blackrect.h - 1) + 1;
- SDL_FillRect(_hwscreen, &blackrect, 0);
+ SDL_FillRect(_hwScreen, &blackrect, 0);
_currentShakePos = _newShakePos;
- _forceFull = true;
+ _forceRedraw = true;
}
// Check whether the palette was changed in the meantime and update the
@@ -1185,7 +1160,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
_paletteDirtyEnd = 0;
- _forceFull = true;
+ _forceRedraw = true;
}
if (!_overlayVisible) {
@@ -1207,7 +1182,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
// Add the area covered by the mouse cursor to the list of dirty rects if
// we have to redraw the mouse.
- if (_mouseNeedsRedraw)
+ if (_cursorNeedsRedraw)
undrawMouse();
#ifdef USE_OSD
@@ -1215,7 +1190,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
#endif
// Force a full redraw if requested
- if (_forceFull) {
+ if (_forceRedraw) {
_numDirtyRects = 1;
_dirtyRectList[0].x = 0;
_dirtyRectList[0].y = 0;
@@ -1224,7 +1199,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
}
// Only draw anything if necessary
- if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+ if (_numDirtyRects > 0 || _cursorNeedsRedraw) {
SDL_Rect *r;
SDL_Rect dst;
uint32 srcPitch, dstPitch;
@@ -1240,10 +1215,10 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
}
SDL_LockSurface(srcSurf);
- SDL_LockSurface(_hwscreen);
+ SDL_LockSurface(_hwScreen);
srcPitch = srcSurf->pitch;
- dstPitch = _hwscreen->pitch;
+ dstPitch = _hwScreen->pitch;
for (r = _dirtyRectList; r != lastRect; ++r) {
register int dst_y = r->y + _currentShakePos;
@@ -1268,7 +1243,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
assert(scalerProc != NULL);
scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
- (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ (byte *)_hwScreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
}
r->x = rx1;
@@ -1278,17 +1253,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
#ifdef USE_SCALERS
if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
- r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
+ r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
#endif
}
SDL_UnlockSurface(srcSurf);
- SDL_UnlockSurface(_hwscreen);
+ SDL_UnlockSurface(_hwScreen);
// Readjust the dirty rect list in case we are doing a full update.
// This is necessary if shaking is active.
- if (_forceFull) {
+ if (_forceRedraw) {
_dirtyRectList[0].y = 0;
- _dirtyRectList[0].h = effectiveScreenHeight();
+ _dirtyRectList[0].h = _videoMode.hardwareHeight;
}
drawMouse();
@@ -1318,18 +1293,18 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
y = real2Aspect(y);
if (h > 0 && w > 0) {
- SDL_LockSurface(_hwscreen);
+ SDL_LockSurface(_hwScreen);
// Use white as color for now.
- Uint32 rectColor = SDL_MapRGB(_hwscreen->format, 0xFF, 0xFF, 0xFF);
+ Uint32 rectColor = SDL_MapRGB(_hwScreen->format, 0xFF, 0xFF, 0xFF);
// First draw the top and bottom lines
// then draw the left and right lines
- if (_hwscreen->format->BytesPerPixel == 2) {
- uint16 *top = (uint16 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
- uint16 *bottom = (uint16 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 2);
- byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
- byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 2);
+ if (_hwScreen->format->BytesPerPixel == 2) {
+ uint16 *top = (uint16 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+ uint16 *bottom = (uint16 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 2);
+ byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+ byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 2);
while (w--) {
*top++ = rectColor;
@@ -1340,14 +1315,14 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
*(uint16 *)left = rectColor;
*(uint16 *)right = rectColor;
- left += _hwscreen->pitch;
- right += _hwscreen->pitch;
+ left += _hwScreen->pitch;
+ right += _hwScreen->pitch;
}
- } else if (_hwscreen->format->BytesPerPixel == 4) {
- uint32 *top = (uint32 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
- uint32 *bottom = (uint32 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 4);
- byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
- byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 4);
+ } else if (_hwScreen->format->BytesPerPixel == 4) {
+ uint32 *top = (uint32 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+ uint32 *bottom = (uint32 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 4);
+ byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+ byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 4);
while (w--) {
*top++ = rectColor;
@@ -1358,12 +1333,12 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
*(uint32 *)left = rectColor;
*(uint32 *)right = rectColor;
- left += _hwscreen->pitch;
- right += _hwscreen->pitch;
+ left += _hwScreen->pitch;
+ right += _hwScreen->pitch;
}
}
- SDL_UnlockSurface(_hwscreen);
+ SDL_UnlockSurface(_hwScreen);
}
}
}
@@ -1371,17 +1346,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
// Finally, blit all our changes to the screen
if (!_displayDisabled) {
- SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+ SDL_UpdateRects(_hwScreen, _numDirtyRects, _dirtyRectList);
}
}
_numDirtyRects = 0;
- _forceFull = false;
- _mouseNeedsRedraw = false;
+ _forceRedraw = false;
+ _cursorNeedsRedraw = false;
}
bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
- assert(_hwscreen != NULL);
+ assert(_hwScreen != NULL);
Common::StackLock lock(_graphicsMutex);
#ifdef USE_PNG
@@ -1391,12 +1366,12 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
- SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwscreen, SDL_PIXELFORMAT_RGB24, 0);
+ SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwScreen, SDL_PIXELFORMAT_RGB24, 0);
#else
// This block of code was taken mostly as-is from SDL 1.2's SDL_SaveBMP_RW
SDL_Surface *rgbScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
- _hwscreen->w,
- _hwscreen->h,
+ _hwScreen->w,
+ _hwScreen->h,
24,
#ifdef SCUMM_LITTLE_ENDIAN
0x0000FF, 0x00FF00, 0xFF0000,
@@ -1411,9 +1386,9 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
SDL_Rect bounds;
bounds.x = bounds.y = 0;
- bounds.w = _hwscreen->w;
- bounds.h = _hwscreen->h;
- if (SDL_LowerBlit(_hwscreen, &bounds, rgbScreen, &bounds) < 0) {
+ bounds.w = _hwScreen->w;
+ bounds.h = _hwScreen->h;
+ if (SDL_LowerBlit(_hwScreen, &bounds, rgbScreen, &bounds) < 0) {
SDL_FreeSurface(rgbScreen);
rgbScreen = nullptr;
}
@@ -1441,7 +1416,7 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
return success;
#else
- return SDL_SaveBMP(_hwscreen, filename) == 0;
+ return SDL_SaveBMP(_hwScreen, filename) == 0;
#endif
}
@@ -1505,7 +1480,6 @@ void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int
if (SDL_LockSurface(_screen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
-#ifdef USE_RGB_COLOR
byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x * _screenFormat.bytesPerPixel;
if (_videoMode.screenWidth == w && pitch == _screen->pitch) {
memcpy(dst, buf, h*pitch);
@@ -1517,19 +1491,6 @@ void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int
dst += _screen->pitch;
} while (--h);
}
-#else
- byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x;
- if (_screen->pitch == pitch && pitch == w) {
- memcpy(dst, buf, h*w);
- } else {
- const byte *src = (const byte *)buf;
- do {
- memcpy(dst, src, w);
- src += pitch;
- dst += _screen->pitch;
- } while (--h);
- }
-#endif
// Unlock the screen surface
SDL_UnlockSurface(_screen);
@@ -1549,13 +1510,7 @@ Graphics::Surface *SurfaceSdlGraphicsManager::lockScreen() {
if (SDL_LockSurface(_screen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
- _framebuffer.init(_screen->w, _screen->h, _screen->pitch, _screen->pixels,
-#ifdef USE_RGB_COLOR
- _screenFormat
-#else
- Graphics::PixelFormat::createFormatCLUT8()
-#endif
- );
+ _framebuffer.init(_screen->w, _screen->h, _screen->pitch, _screen->pixels, _screenFormat);
return &_framebuffer;
}
@@ -1571,7 +1526,7 @@ void SurfaceSdlGraphicsManager::unlockScreen() {
SDL_UnlockSurface(_screen);
// Trigger a full screen update
- _forceFull = true;
+ _forceRedraw = true;
// Finally unlock the graphics mutex
g_system->unlockMutex(_graphicsMutex);
@@ -1585,11 +1540,11 @@ void SurfaceSdlGraphicsManager::fillScreen(uint32 col) {
}
void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool realCoordinates) {
- if (_forceFull)
+ if (_forceRedraw)
return;
if (_numDirtyRects == NUM_DIRTY_RECT) {
- _forceFull = true;
+ _forceRedraw = true;
return;
}
@@ -1608,8 +1563,8 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
if (!realCoordinates) {
x--;
y--;
- w+=2;
- h+=2;
+ w += 2;
+ h += 2;
}
// clip
@@ -1620,7 +1575,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
if (y < 0) {
h += y;
- y=0;
+ y = 0;
}
if (w > width - x) {
@@ -1638,7 +1593,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
#endif
if (w == width && h == height) {
- _forceFull = true;
+ _forceRedraw = true;
return;
}
@@ -1652,20 +1607,17 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
}
}
-int16 SurfaceSdlGraphicsManager::getHeight() {
+int16 SurfaceSdlGraphicsManager::getHeight() const {
return _videoMode.screenHeight;
}
-int16 SurfaceSdlGraphicsManager::getWidth() {
+int16 SurfaceSdlGraphicsManager::getWidth() const {
return _videoMode.screenWidth;
}
void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
assert(colors);
-
-#ifdef USE_RGB_COLOR
assert(_screenFormat.bytesPerPixel == 1);
-#endif
// Setting the palette before _screen is created is allowed - for now -
// since we don't actually set the palette until the screen is updated.
@@ -1697,12 +1649,9 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
blitCursor();
}
-void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
assert(colors);
-
-#ifdef USE_RGB_COLOR
assert(_screenFormat.bytesPerPixel == 1);
-#endif
const SDL_Color *base = _currentPalette + start;
@@ -1777,56 +1726,7 @@ void SurfaceSdlGraphicsManager::clearFocusRectangle() {
#pragma mark --- Overlays ---
#pragma mark -
-void SurfaceSdlGraphicsManager::showOverlay() {
- assert(_transactionMode == kTransactionNone);
-
- int x, y;
-
- if (_overlayVisible)
- return;
-
- _overlayVisible = true;
-
- // Since resolution could change, put mouse to adjusted position
- // Fixes bug #1349059
- x = _mouseCurState.x * _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
- else
- y = _mouseCurState.y * _videoMode.scaleFactor;
-
- warpMouse(x, y);
-
- clearOverlay();
-}
-
-void SurfaceSdlGraphicsManager::hideOverlay() {
- assert(_transactionMode == kTransactionNone);
-
- if (!_overlayVisible)
- return;
-
- int x, y;
-
- _overlayVisible = false;
-
- // Since resolution could change, put mouse to adjusted position
- // Fixes bug #1349059
- x = _mouseCurState.x / _videoMode.scaleFactor;
- y = _mouseCurState.y / _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- y = aspect2Real(y);
-
- warpMouse(x, y);
-
- clearOverlay();
-
- _forceFull = true;
-}
-
void SurfaceSdlGraphicsManager::clearOverlay() {
- //assert(_transactionMode == kTransactionNone);
-
Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
if (!_overlayVisible)
@@ -1854,10 +1754,10 @@ void SurfaceSdlGraphicsManager::clearOverlay() {
SDL_UnlockSurface(_tmpscreen);
SDL_UnlockSurface(_overlayscreen);
- _forceFull = true;
+ _forceRedraw = true;
}
-void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) {
+void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) const {
assert(_transactionMode == kTransactionNone);
if (_overlayscreen == NULL)
@@ -1931,143 +1831,159 @@ void SurfaceSdlGraphicsManager::copyRectToOverlay(const void *buf, int pitch, in
#pragma mark --- Mouse ---
#pragma mark -
-bool SurfaceSdlGraphicsManager::showMouse(bool visible) {
- if (_mouseVisible == visible)
- return visible;
+void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keyColor, bool dontScale, const Graphics::PixelFormat *format) {
+ if (format) {
+#ifndef USE_RGB_COLOR
+ assert(format->bytesPerPixel == 1);
+#endif
+ _cursorFormat = *format;
+ } else {
+ _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+ }
- bool last = _mouseVisible;
- _mouseVisible = visible;
- _mouseNeedsRedraw = true;
+ if (_cursorFormat.bytesPerPixel == 4) {
+ assert(keyColor == 0);
+ dontScale = true;
+ } else {
+ assert(keyColor < 1U << (_cursorFormat.bytesPerPixel * 8));
+ }
- return last;
-}
+ _mouseCurState.hotX = hotspotX;
+ _mouseCurState.hotY = hotspotY;
-void SurfaceSdlGraphicsManager::setMousePos(int x, int y) {
- if (x != _mouseCurState.x || y != _mouseCurState.y) {
- _mouseNeedsRedraw = true;
- _mouseCurState.x = x;
- _mouseCurState.y = y;
- }
-}
+ _mouseKeyColor = keyColor;
-void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
- // Don't change actual mouse position, when mouse is outside of our window (in case of windowed mode)
- if (!_window->hasMouseFocus()) {
- setMousePos(x, y); // but change game cursor position
- return;
- }
+ _cursorDontScale = dontScale;
- int x1 = x, y1 = y;
- if (_videoMode.aspectRatioCorrection && !_overlayVisible)
- y1 = real2Aspect(y1);
+ if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
+ _mouseCurState.w = w;
+ _mouseCurState.h = h;
- if (_mouseCurState.x != x || _mouseCurState.y != y) {
- if (!_overlayVisible) {
- x1 *= _videoMode.scaleFactor;
- y1 *= _videoMode.scaleFactor;
+ if (!w || !h) {
+ return;
}
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- // Transform our coordinates in "virtual" output coordinate space into
- // actual output coordinate space.
- x1 = x1 * _windowWidth / _videoMode.hardwareWidth;
- y1 = y1 * _windowHeight / _videoMode.hardwareHeight;
-#endif
+ if (_mouseOrigSurface) {
+ SDL_FreeSurface(_mouseOrigSurface);
+
+ if (_mouseSurface == _mouseOrigSurface) {
+ _mouseSurface = nullptr;
+ }
+ }
+
+ if (_cursorFormat.bytesPerPixel == 4) {
+ if (_mouseSurface != _mouseOrigSurface) {
+ SDL_FreeSurface(_mouseSurface);
+ }
- _window->warpMouseInWindow(x1, y1);
+ const Uint32 rMask = ((0xFF >> format->rLoss) << format->rShift);
+ const Uint32 gMask = ((0xFF >> format->gLoss) << format->gShift);
+ const Uint32 bMask = ((0xFF >> format->bLoss) << format->bShift);
+ const Uint32 aMask = ((0xFF >> format->aLoss) << format->aShift);
+ _mouseSurface = _mouseOrigSurface = SDL_CreateRGBSurfaceFrom(const_cast<void *>(buf), w, h, format->bytesPerPixel * 8, w * format->bytesPerPixel, rMask, gMask, bMask, aMask);
+ } else {
+ // Allocate bigger surface because AdvMame2x adds black pixel at [0,0]
+ _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
+ _mouseCurState.w + 2,
+ _mouseCurState.h + 2,
+ 16,
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
+ }
- // SDL_WarpMouse() generates a mouse movement event, so
- // setMousePos() would be called eventually. However, the
- // cannon script in CoMI calls this function twice each time
- // the cannon is reloaded. Unless we update the mouse position
- // immediately the second call is ignored, causing the cannon
- // to change its aim.
+ if (_mouseOrigSurface == nullptr) {
+ error("Allocating _mouseOrigSurface failed");
+ }
- setMousePos(x, y);
+ if (_cursorFormat.bytesPerPixel < 4) {
+ SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
+ }
}
-}
-void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
-#ifdef USE_RGB_COLOR
- if (!format)
- _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
- else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel)
- _cursorFormat = *format;
+ delete[] _mouseData;
+ if (_cursorFormat.bytesPerPixel == 4) {
+ _mouseData = nullptr;
+ } else {
+ _mouseData = new byte[w * h * _cursorFormat.bytesPerPixel];
+ assert(_mouseData);
+ memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
+ }
- if (_cursorFormat.bytesPerPixel < 4)
- assert(keycolor < (uint)(1 << (_cursorFormat.bytesPerPixel << 3)));
-#else
- assert(keycolor <= 0xFF);
-#endif
+ blitCursor();
+}
- if (w == 0 || h == 0)
+void SurfaceSdlGraphicsManager::blitCursor() {
+ const int w = _mouseCurState.w;
+ const int h = _mouseCurState.h;
+
+ if (!w || !h || !_mouseOrigSurface) {
return;
+ }
- _mouseCurState.hotX = hotspot_x;
- _mouseCurState.hotY = hotspot_y;
+ if (_cursorFormat.bytesPerPixel != 4 && !_mouseData) {
+ return;
+ }
- _mouseKeyColor = keycolor;
+ _cursorNeedsRedraw = true;
- _cursorDontScale = dontScale;
+ int cursorScale;
+ if (_cursorDontScale) {
+ // Don't scale the cursor at all if the user requests this behavior.
+ cursorScale = 1;
+ } else {
+ // Scale the cursor with the game screen scale factor.
+ cursorScale = _videoMode.scaleFactor;
+ }
- if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
- _mouseCurState.w = w;
- _mouseCurState.h = h;
+ assert(_cursorFormat.bytesPerPixel != 4 || cursorScale == 1);
- if (_mouseOrigSurface)
- SDL_FreeSurface(_mouseOrigSurface);
+ // Adapt the real hotspot according to the scale factor.
+ int rW = w * cursorScale;
+ int rH = h * cursorScale;
+ _mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
+ _mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
- // Allocate bigger surface because AdvMame2x adds black pixel at [0,0]
- _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
- _mouseCurState.w + 2,
- _mouseCurState.h + 2,
- 16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ // The virtual dimensions will be the same as the original.
- if (_mouseOrigSurface == NULL)
- error("allocating _mouseOrigSurface failed");
- SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
- }
+ _mouseCurState.vW = w;
+ _mouseCurState.vH = h;
+ _mouseCurState.vHotX = _mouseCurState.hotX;
+ _mouseCurState.vHotY = _mouseCurState.hotY;
- free(_mouseData);
-#ifdef USE_RGB_COLOR
- _mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
- memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
-#else
- _mouseData = (byte *)malloc(w * h);
- memcpy(_mouseData, buf, w * h);
+#ifdef USE_SCALERS
+ // store original to pass to aspect-correction function later
+ const int rH1 = rH;
#endif
- blitCursor();
-}
+ if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
+ rH = real2Aspect(rH - 1) + 1;
+ _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
+ }
-void SurfaceSdlGraphicsManager::blitCursor() {
- byte *dstPtr;
- const byte *srcPtr = _mouseData;
-#ifdef USE_RGB_COLOR
- uint32 color;
-#else
- byte color;
-#endif
- int w, h, i, j;
+ bool sizeChanged = false;
+ if (_mouseCurState.rW != rW || _mouseCurState.rH != rH) {
+ _mouseCurState.rW = rW;
+ _mouseCurState.rH = rH;
+ sizeChanged = true;
+ }
- if (!_mouseOrigSurface || !_mouseData)
+ // 32bpp always blits directly, so no need to do any more work here
+ if (_cursorFormat.bytesPerPixel == 4) {
return;
-
- _mouseNeedsRedraw = true;
-
- w = _mouseCurState.w;
- h = _mouseCurState.h;
+ }
SDL_LockSurface(_mouseOrigSurface);
+ byte *dstPtr;
+ const byte *srcPtr = _mouseData;
+ uint32 color;
+
// Make whole surface transparent
- for (i = 0; i < h + 2; i++) {
+ for (int i = 0; i < h + 2; i++) {
dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch * i;
- for (j = 0; j < w + 2; j++) {
+ for (int j = 0; j < w + 2; j++) {
*(uint16 *)dstPtr = kMouseColorKey;
dstPtr += 2;
}
@@ -2083,75 +1999,31 @@ void SurfaceSdlGraphicsManager::blitCursor() {
else
palette = _cursorPalette;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
-#ifdef USE_RGB_COLOR
- if (_cursorFormat.bytesPerPixel > 1) {
- if (_cursorFormat.bytesPerPixel == 2)
- color = *(const uint16 *)srcPtr;
- else
- color = *(const uint32 *)srcPtr;
- if (color != _mouseKeyColor) { // transparent, don't draw
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ if (_cursorFormat.bytesPerPixel == 2) {
+ color = *(const uint16 *)srcPtr;
+ if (color != _mouseKeyColor) {
uint8 r, g, b;
_cursorFormat.colorToRGB(color, r, g, b);
- *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
- r, g, b);
+ *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, r, g, b);
}
dstPtr += 2;
srcPtr += _cursorFormat.bytesPerPixel;
} else {
-#endif
color = *srcPtr;
- if (color != _mouseKeyColor) { // transparent, don't draw
+ if (color != _mouseKeyColor) {
*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
palette[color].r, palette[color].g, palette[color].b);
}
dstPtr += 2;
srcPtr++;
-#ifdef USE_RGB_COLOR
}
-#endif
}
dstPtr += _mouseOrigSurface->pitch - w * 2;
}
- int rW, rH;
- int cursorScale;
-
- if (_cursorDontScale) {
- // Don't scale the cursor at all if the user requests this behavior.
- cursorScale = 1;
- } else {
- // Scale the cursor with the game screen scale factor.
- cursorScale = _videoMode.scaleFactor;
- }
-
- // Adapt the real hotspot according to the scale factor.
- rW = w * cursorScale;
- rH = h * cursorScale;
- _mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
- _mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
-
- // The virtual dimensions will be the same as the original.
-
- _mouseCurState.vW = w;
- _mouseCurState.vH = h;
- _mouseCurState.vHotX = _mouseCurState.hotX;
- _mouseCurState.vHotY = _mouseCurState.hotY;
-
-#ifdef USE_SCALERS
- int rH1 = rH; // store original to pass to aspect-correction function later
-#endif
-
- if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
- rH = real2Aspect(rH - 1) + 1;
- _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
- }
-
- if (_mouseCurState.rW != rW || _mouseCurState.rH != rH) {
- _mouseCurState.rW = rW;
- _mouseCurState.rH = rH;
-
+ if (sizeChanged) {
if (_mouseSurface)
SDL_FreeSurface(_mouseSurface);
@@ -2159,13 +2031,13 @@ void SurfaceSdlGraphicsManager::blitCursor() {
_mouseCurState.rW,
_mouseCurState.rH,
16,
- _hwscreen->format->Rmask,
- _hwscreen->format->Gmask,
- _hwscreen->format->Bmask,
- _hwscreen->format->Amask);
+ _hwScreen->format->Rmask,
+ _hwScreen->format->Gmask,
+ _hwScreen->format->Bmask,
+ _hwScreen->format->Amask);
- if (_mouseSurface == NULL)
- error("allocating _mouseSurface failed");
+ if (_mouseSurface == nullptr)
+ error("Allocating _mouseSurface failed");
SDL_SetColorKey(_mouseSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
}
@@ -2236,7 +2108,7 @@ void SurfaceSdlGraphicsManager::undrawMouse() {
}
void SurfaceSdlGraphicsManager::drawMouse() {
- if (!_mouseVisible || !_mouseSurface) {
+ if (!_cursorVisible || !_mouseSurface || !_mouseCurState.w || !_mouseCurState.h) {
_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
return;
}
@@ -2245,8 +2117,10 @@ void SurfaceSdlGraphicsManager::drawMouse() {
int scale;
int hotX, hotY;
- dst.x = _mouseCurState.x;
- dst.y = _mouseCurState.y;
+ const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
+
+ dst.x = virtualCursor.x;
+ dst.y = virtualCursor.y;
if (!_overlayVisible) {
scale = _videoMode.scaleFactor;
@@ -2283,10 +2157,17 @@ void SurfaceSdlGraphicsManager::drawMouse() {
dst.w = _mouseCurState.rW;
dst.h = _mouseCurState.rH;
+ // Alpha-blended cursors will happily blend into themselves if the hardware
+ // surface under the cursor is not reset first
+ if (!_forceRedraw && _cursorFormat.bytesPerPixel == 4) {
+ if (SDL_BlitSurface(_screen, &dst, _hwScreen, &dst) != 0)
+ error("SD_BlitSurface failed: %s", SDL_GetError());
+ }
+
// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
// clipping necessary
- if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
+ if (SDL_BlitSurface(_mouseSurface, nullptr, _hwScreen, &dst) != 0)
error("SDL_BlitSurface failed: %s", SDL_GetError());
// The screen will be updated using real surface coordinates, i.e.
@@ -2335,14 +2216,14 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
}
// Clip the rect
- if (width > _hwscreen->w)
- width = _hwscreen->w;
- if (height > _hwscreen->h)
- height = _hwscreen->h;
+ if (width > _hwScreen->w)
+ width = _hwScreen->w;
+ if (height > _hwScreen->h)
+ height = _hwScreen->h;
_osdMessageSurface = SDL_CreateRGBSurface(
SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCALPHA,
- width, height, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask
+ width, height, 16, _hwScreen->format->Rmask, _hwScreen->format->Gmask, _hwScreen->format->Bmask, _hwScreen->format->Amask
);
// Lock the surface
@@ -2379,8 +2260,8 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
SDL_Rect SurfaceSdlGraphicsManager::getOSDMessageRect() const {
SDL_Rect rect;
- rect.x = (_hwscreen->w - _osdMessageSurface->w) / 2;
- rect.y = (_hwscreen->h - _osdMessageSurface->h) / 2;
+ rect.x = (_hwScreen->w - _osdMessageSurface->w) / 2;
+ rect.y = (_hwScreen->h - _osdMessageSurface->h) / 2;
rect.w = _osdMessageSurface->w;
rect.h = _osdMessageSurface->h;
return rect;
@@ -2393,7 +2274,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
if (_osdIconSurface && !icon) {
// Force a redraw to clear the icon on the next update
- _forceFull = true;
+ _forceRedraw = true;
}
if (_osdIconSurface) {
@@ -2432,7 +2313,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
SDL_Rect SurfaceSdlGraphicsManager::getOSDIconRect() const {
SDL_Rect dstRect;
- dstRect.x = _hwscreen->w - _osdIconSurface->w - 10;
+ dstRect.x = _hwScreen->w - _osdIconSurface->w - 10;
dstRect.y = 10;
dstRect.w = _osdIconSurface->w;
dstRect.h = _osdIconSurface->h;
@@ -2464,7 +2345,7 @@ void SurfaceSdlGraphicsManager::updateOSD() {
_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
}
SDL_SetAlpha(_osdMessageSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdMessageAlpha);
- _forceFull = true;
+ _forceRedraw = true;
}
if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
@@ -2474,26 +2355,30 @@ void SurfaceSdlGraphicsManager::updateOSD() {
if (_osdIconSurface) {
// Redraw the area below the icon for the transparent blit to give correct results.
- _forceFull = true;
+ _forceRedraw = true;
}
}
void SurfaceSdlGraphicsManager::drawOSD() {
if (_osdMessageSurface) {
SDL_Rect dstRect = getOSDMessageRect();
- SDL_BlitSurface(_osdMessageSurface, 0, _hwscreen, &dstRect);
+ SDL_BlitSurface(_osdMessageSurface, 0, _hwScreen, &dstRect);
}
if (_osdIconSurface) {
SDL_Rect dstRect = getOSDIconRect();
- SDL_BlitSurface(_osdIconSurface, 0, _hwscreen, &dstRect);
+ SDL_BlitSurface(_osdIconSurface, 0, _hwScreen, &dstRect);
}
}
#endif
-bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
+void SurfaceSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+ SdlGraphicsManager::handleResizeImpl(width, height);
+ recalculateDisplayAreas();
+}
+bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
// Ctrl-Alt-a toggles aspect ratio correction
if (key == 'a') {
beginGFXTransaction();
@@ -2505,13 +2390,13 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
message = Common::String::format("%s\n%d x %d -> %d x %d",
_("Enabled aspect ratio correction"),
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
+ _hwScreen->w, _hwScreen->h
);
else
message = Common::String::format("%s\n%d x %d -> %d x %d",
_("Disabled aspect ratio correction"),
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
+ _hwScreen->w, _hwScreen->h
);
displayMessageOnOSD(message.c_str());
#endif
@@ -2532,7 +2417,7 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
displayMessageOnOSD(_("Filtering disabled"));
}
#endif
- _forceFull = true;
+ _forceRedraw = true;
internUpdateScreen();
return true;
}
@@ -2542,12 +2427,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
int factor = _videoMode.scaleFactor - 1;
SDLKey sdlKey = (SDLKey)key;
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ bool sizeChanged = false;
+#endif
+
// Increase/decrease the scale factor
if (sdlKey == SDLK_EQUALS || sdlKey == SDLK_PLUS || sdlKey == SDLK_MINUS ||
sdlKey == SDLK_KP_PLUS || sdlKey == SDLK_KP_MINUS) {
factor += (sdlKey == SDLK_MINUS || sdlKey == SDLK_KP_MINUS) ? -1 : +1;
if (0 <= factor && factor <= 3) {
newMode = s_gfxModeSwitchTable[_scalerType][factor];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ sizeChanged = true;
+#endif
}
}
@@ -2585,10 +2477,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
_("Active graphics filter:"),
newScalerName,
_videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h);
+ _hwScreen->w, _hwScreen->h);
displayMessageOnOSD(message.c_str());
}
#endif
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (sizeChanged) {
+ // Forcibly resizing the window here since a user switching scaler
+ // size will not normally cause the window to update
+ _window->createOrUpdateWindow(_hwScreen->w, _hwScreen->h, _lastFlags);
+ }
+#endif
+
internUpdateScreen();
return true;
@@ -2700,37 +2601,11 @@ bool SurfaceSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
void SurfaceSdlGraphicsManager::notifyVideoExpose() {
- _forceFull = true;
+ _forceRedraw = true;
}
-void SurfaceSdlGraphicsManager::notifyResize(const uint width, const uint height) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- setWindowResolution(width, height);
-#endif
-}
-
-void SurfaceSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
- // In SDL2 the actual output resolution might be different from what we
- // requested. Thus, we transform the coordinates from actual output
- // coordinate space into the "virtual" output coordinate space.
- // Please note that we ignore the possible existence of black bars here,
- // this avoids the feeling of stickyness to black bars.
- point.x = point.x * _videoMode.hardwareWidth / _windowWidth;
- point.y = point.y * _videoMode.hardwareHeight / _windowHeight;
-#endif
-
- if (!_overlayVisible) {
- point.x /= _videoMode.scaleFactor;
- point.y /= _videoMode.scaleFactor;
- if (_videoMode.aspectRatioCorrection)
- point.y = aspect2Real(point.y);
- }
-}
-
-void SurfaceSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
- transformMouseCoordinates(mouse);
- setMousePos(mouse.x, mouse.y);
+void SurfaceSdlGraphicsManager::notifyResize(const int width, const int height) {
+ handleResize(width, height);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -2742,39 +2617,6 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
_renderer = nullptr;
}
-void SurfaceSdlGraphicsManager::setWindowResolution(int width, int height) {
- _windowWidth = width;
- _windowHeight = height;
-
- // We expect full screen resolution as inputs coming from the event system.
- _eventSource->resetKeyboardEmulation(_windowWidth - 1, _windowHeight - 1);
-
- // Calculate the "viewport" for the actual area we draw in. In fullscreen
- // we can easily get a different resolution than what we requested. In
- // this case, we add black bars if necessary to assure the aspect ratio
- // is preserved.
- const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
- const frac_t desiredAspect = intToFrac(_videoMode.hardwareWidth) / _videoMode.hardwareHeight;
-
- _viewport.w = _windowWidth;
- _viewport.h = _windowHeight;
-
- // Adjust one dimension for mantaining the aspect ratio.
- if (abs(outputAspect - desiredAspect) >= (int)(FRAC_ONE / 1000)) {
- if (outputAspect < desiredAspect) {
- _viewport.h = _videoMode.hardwareHeight * _windowWidth / _videoMode.hardwareWidth;
- } else if (outputAspect > desiredAspect) {
- _viewport.w = _videoMode.hardwareWidth * _windowHeight / _videoMode.hardwareHeight;
- }
- }
-
- _viewport.x = (_windowWidth - _viewport.w) / 2;
- _viewport.y = (_windowHeight - _viewport.h) / 2;
-
- // Force a full redraw because we changed the viewport.
- _forceFull = true;
-}
-
void SurfaceSdlGraphicsManager::recreateScreenTexture() {
if (!_renderer)
return;
@@ -2792,10 +2634,7 @@ void SurfaceSdlGraphicsManager::recreateScreenTexture() {
SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
deinitializeRenderer();
- uint32 createWindowFlags = 0;
-#ifdef USE_SDL_RESIZABLE_WINDOW
- createWindowFlags |= SDL_WINDOW_RESIZABLE;
-#endif
+ uint32 createWindowFlags = SDL_WINDOW_RESIZABLE;
if ((flags & SDL_FULLSCREEN) != 0) {
createWindowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
@@ -2810,8 +2649,8 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
return nullptr;
}
- SDL_GetWindowSize(_window->getSDLWindow(), &_windowWidth, &_windowHeight);
- setWindowResolution(_windowWidth, _windowHeight);
+ getWindowSizeFromSdl(&_windowWidth, &_windowHeight);
+ handleResize(_windowWidth, _windowHeight);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, _videoMode.filtering ? "linear" : "nearest");
@@ -2833,8 +2672,14 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
+ SDL_Rect viewport;
+ viewport.x = _activeArea.drawRect.left;
+ viewport.y = _activeArea.drawRect.top;
+ viewport.w = _activeArea.drawRect.width();
+ viewport.h = _activeArea.drawRect.height();
+
SDL_RenderClear(_renderer);
- SDL_RenderCopy(_renderer, _screenTexture, NULL, &_viewport);
+ SDL_RenderCopy(_renderer, _screenTexture, NULL, &viewport);
SDL_RenderPresent(_renderer);
}
#endif // SDL_VERSION_ATLEAST(2, 0, 0)
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 62a4a38d3e..60f5d29f55 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -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 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 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 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 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 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
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
index c17cfd5efa..227674f811 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
@@ -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:
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.h b/backends/graphics/symbiansdl/symbiansdl-graphics.h
index fb9a49a834..0fcfb70f24 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.h
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.h
@@ -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
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
index 44a1214a44..1677ecac06 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.cpp
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -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;
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
index 9316c69e44..4842d49023 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.h
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -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);
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
new file mode 100644
index 0000000000..1d4958c9d6
--- /dev/null
+++ b/backends/graphics/windowed.h
@@ -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
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index c9adbd3100..944ddd5a47 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -217,6 +217,7 @@ bool ModularBackend::showMouse(bool visible) {
}
void ModularBackend::warpMouse(int x, int y) {
+ _eventManager->purgeMouseEvents();
_graphicsManager->warpMouse(x, y);
}
diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
index 75cf813638..fe27d84de2 100644
--- a/backends/platform/sdl/sdl-window.cpp
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -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() {
diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h
index d75e811f56..e1a3499d19 100644
--- a/backends/platform/sdl/sdl-window.h
+++ b/backends/platform/sdl/sdl-window.h
@@ -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
};
diff --git a/common/events.h b/common/events.h
index 21a65a642b..e5bb8cab50 100644
--- a/common/events.h
+++ b/common/events.h
@@ -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;
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 5fcd2a3602..678b074360 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -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());
}
diff --git a/graphics/palette.h b/graphics/palette.h
index 2884bef7f4..0b9b861aa9 100644
--- a/graphics/palette.h
+++ b/graphics/palette.h
@@ -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