mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 09:36:21 +00:00
Merge branch 'graphics-backends-improvements'
This commit is contained in:
commit
7d8d2f80fb
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -36,26 +36,23 @@ class DINGUXSdlGraphicsManager : public SurfaceSdlGraphicsManager {
|
||||
public:
|
||||
DINGUXSdlGraphicsManager(SdlEventSource *boss, SdlWindow *window);
|
||||
|
||||
bool hasFeature(OSystem::Feature f);
|
||||
void setFeatureState(OSystem::Feature f, bool enable);
|
||||
bool getFeatureState(OSystem::Feature f);
|
||||
int getDefaultGraphicsMode() const;
|
||||
bool hasFeature(OSystem::Feature f) const override;
|
||||
void setFeatureState(OSystem::Feature f, bool enable) override;
|
||||
bool getFeatureState(OSystem::Feature f) override;
|
||||
int getDefaultGraphicsMode() const override;
|
||||
|
||||
void initSize(uint w, uint h);
|
||||
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
|
||||
bool setGraphicsMode(const char *name);
|
||||
bool setGraphicsMode(int mode);
|
||||
void setGraphicsModeIntern();
|
||||
void internUpdateScreen();
|
||||
void showOverlay();
|
||||
void hideOverlay();
|
||||
bool loadGFXMode();
|
||||
void drawMouse();
|
||||
void undrawMouse();
|
||||
virtual void warpMouse(int x, int y);
|
||||
|
||||
SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
|
||||
SurfaceSdlGraphicsManager::VideoState *getVideoMode();
|
||||
void initSize(uint w, uint h) override;
|
||||
const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
|
||||
bool setGraphicsMode(const char *name) override;
|
||||
bool setGraphicsMode(int mode) override;
|
||||
void setGraphicsModeIntern() override;
|
||||
void internUpdateScreen() override;
|
||||
void showOverlay() override;
|
||||
void hideOverlay() override;
|
||||
bool loadGFXMode() override;
|
||||
void drawMouse() override;
|
||||
void undrawMouse() override;
|
||||
void warpMouse(int x, int y) override;
|
||||
|
||||
virtual void transformMouseCoordinates(Common::Point &point);
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -35,26 +35,23 @@ class GPHGraphicsManager : public SurfaceSdlGraphicsManager {
|
||||
public:
|
||||
GPHGraphicsManager(SdlEventSource *boss, SdlWindow *window);
|
||||
|
||||
bool hasFeature(OSystem::Feature f);
|
||||
void setFeatureState(OSystem::Feature f, bool enable);
|
||||
bool getFeatureState(OSystem::Feature f);
|
||||
int getDefaultGraphicsMode() const;
|
||||
bool hasFeature(OSystem::Feature f) const override;
|
||||
void setFeatureState(OSystem::Feature f, bool enable) override;
|
||||
bool getFeatureState(OSystem::Feature f) const;
|
||||
int getDefaultGraphicsMode() const override;
|
||||
|
||||
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
|
||||
const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
|
||||
bool setGraphicsMode(const char *name);
|
||||
bool setGraphicsMode(int mode);
|
||||
void setGraphicsModeIntern();
|
||||
void internUpdateScreen();
|
||||
void showOverlay();
|
||||
void hideOverlay();
|
||||
bool loadGFXMode();
|
||||
void drawMouse();
|
||||
void undrawMouse();
|
||||
virtual void warpMouse(int x, int y);
|
||||
|
||||
SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
|
||||
SurfaceSdlGraphicsManager::VideoState *getVideoMode();
|
||||
void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
|
||||
const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
|
||||
bool setGraphicsMode(const char *name) override;
|
||||
bool setGraphicsMode(int mode) override;
|
||||
void setGraphicsModeIntern() override;
|
||||
void internUpdateScreen() override;
|
||||
void showOverlay() override;
|
||||
void hideOverlay() override;
|
||||
bool loadGFXMode() override;
|
||||
void drawMouse() override;
|
||||
void undrawMouse() override;
|
||||
void warpMouse(int x, int y) override;
|
||||
|
||||
virtual void transformMouseCoordinates(Common::Point &point);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
|
||||
|
||||
protected:
|
||||
virtual bool loadGFXMode();
|
||||
virtual bool loadGFXMode() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "backends/graphics/opengl/opengl-sys.h"
|
||||
#include "backends/graphics/opengl/framebuffer.h"
|
||||
#include "backends/graphics/graphics.h"
|
||||
#include "backends/graphics/windowed.h"
|
||||
|
||||
#include "common/frac.h"
|
||||
#include "common/mutex.h"
|
||||
@ -53,74 +53,69 @@ enum {
|
||||
GFX_OPENGL = 0
|
||||
};
|
||||
|
||||
class OpenGLGraphicsManager : virtual public GraphicsManager {
|
||||
class OpenGLGraphicsManager : virtual public WindowedGraphicsManager {
|
||||
public:
|
||||
OpenGLGraphicsManager();
|
||||
virtual ~OpenGLGraphicsManager();
|
||||
|
||||
// GraphicsManager API
|
||||
virtual bool hasFeature(OSystem::Feature f);
|
||||
virtual void setFeatureState(OSystem::Feature f, bool enable);
|
||||
virtual bool getFeatureState(OSystem::Feature f);
|
||||
virtual bool hasFeature(OSystem::Feature f) const override;
|
||||
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
|
||||
virtual bool getFeatureState(OSystem::Feature f) const override;
|
||||
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
|
||||
virtual int getDefaultGraphicsMode() const;
|
||||
virtual bool setGraphicsMode(int mode);
|
||||
virtual int getGraphicsMode() const;
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
|
||||
virtual int getDefaultGraphicsMode() const override;
|
||||
virtual bool setGraphicsMode(int mode) override;
|
||||
virtual int getGraphicsMode() const override;
|
||||
|
||||
virtual void resetGraphicsScale() {}
|
||||
virtual void resetGraphicsScale() override {}
|
||||
|
||||
#ifdef USE_RGB_COLOR
|
||||
virtual Graphics::PixelFormat getScreenFormat() const;
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
|
||||
virtual Graphics::PixelFormat getScreenFormat() const override;
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override = 0;
|
||||
#endif
|
||||
|
||||
virtual void beginGFXTransaction();
|
||||
virtual OSystem::TransactionError endGFXTransaction();
|
||||
virtual void beginGFXTransaction() override;
|
||||
virtual OSystem::TransactionError endGFXTransaction() override;
|
||||
|
||||
virtual int getScreenChangeID() const;
|
||||
virtual int getScreenChangeID() const override;
|
||||
|
||||
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
|
||||
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
|
||||
|
||||
virtual int16 getWidth();
|
||||
virtual int16 getHeight();
|
||||
virtual int16 getWidth() const override;
|
||||
virtual int16 getHeight() const override;
|
||||
|
||||
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual void fillScreen(uint32 col);
|
||||
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
|
||||
virtual void fillScreen(uint32 col) override;
|
||||
|
||||
virtual void setShakePos(int shakeOffset);
|
||||
virtual void setShakePos(int shakeOffset) override;
|
||||
|
||||
virtual void updateScreen();
|
||||
virtual void updateScreen() override;
|
||||
|
||||
virtual Graphics::Surface *lockScreen();
|
||||
virtual void unlockScreen();
|
||||
virtual Graphics::Surface *lockScreen() override;
|
||||
virtual void unlockScreen() override;
|
||||
|
||||
virtual void setFocusRectangle(const Common::Rect& rect);
|
||||
virtual void clearFocusRectangle();
|
||||
virtual void setFocusRectangle(const Common::Rect& rect) override;
|
||||
virtual void clearFocusRectangle() override;
|
||||
|
||||
virtual int16 getOverlayWidth();
|
||||
virtual int16 getOverlayHeight();
|
||||
virtual int16 getOverlayWidth() const override;
|
||||
virtual int16 getOverlayHeight() const override;
|
||||
|
||||
virtual void showOverlay();
|
||||
virtual void hideOverlay();
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const override;
|
||||
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const;
|
||||
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
|
||||
virtual void clearOverlay() override;
|
||||
virtual void grabOverlay(void *buf, int pitch) const override;
|
||||
|
||||
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual void clearOverlay();
|
||||
virtual void grabOverlay(void *buf, int pitch);
|
||||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) override;
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
|
||||
|
||||
virtual bool showMouse(bool visible);
|
||||
virtual void warpMouse(int x, int y);
|
||||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
|
||||
virtual void displayMessageOnOSD(const char *msg);
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
|
||||
virtual void displayMessageOnOSD(const char *msg) override;
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
|
||||
|
||||
// PaletteManager interface
|
||||
virtual void setPalette(const byte *colors, uint start, uint num);
|
||||
virtual void grabPalette(byte *colors, uint start, uint num);
|
||||
virtual void setPalette(const byte *colors, uint start, uint num) override;
|
||||
virtual void grabPalette(byte *colors, uint start, uint num) const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -128,15 +123,6 @@ protected:
|
||||
*/
|
||||
bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
|
||||
|
||||
/**
|
||||
* Set up the actual screen size available for the OpenGL code to do any
|
||||
* drawing.
|
||||
*
|
||||
* @param width The width of the screen.
|
||||
* @param height The height of the screen.
|
||||
*/
|
||||
void setActualScreenSize(uint width, uint height);
|
||||
|
||||
/**
|
||||
* Sets the OpenGL (ES) type the graphics manager shall work with.
|
||||
*
|
||||
@ -166,33 +152,6 @@ protected:
|
||||
*/
|
||||
void notifyContextDestroy();
|
||||
|
||||
/**
|
||||
* Adjust the physical mouse coordinates according to the currently visible screen.
|
||||
*/
|
||||
void adjustMousePosition(int16 &x, int16 &y);
|
||||
|
||||
/**
|
||||
* Set up the mouse position for graphics output.
|
||||
*
|
||||
* @param x X coordinate in physical coordinates.
|
||||
* @param y Y coordinate in physical coordinates.
|
||||
*/
|
||||
void setMousePosition(int x, int y);
|
||||
|
||||
/**
|
||||
* Query the mouse position in physical coordinates.
|
||||
*/
|
||||
void getMousePosition(int16 &x, int16 &y) const { x = _cursorX; y = _cursorY; }
|
||||
|
||||
/**
|
||||
* Set up the mouse position for the (event) system.
|
||||
*
|
||||
* @param x X coordinate in physical coordinates.
|
||||
* @param y Y coordinate in physical coordinates.
|
||||
*/
|
||||
virtual void setInternalMousePosition(int x, int y) = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create a surface with the specified pixel format.
|
||||
*
|
||||
@ -241,7 +200,7 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* The currently setup video state.
|
||||
* The currently set up video state.
|
||||
*/
|
||||
VideoState _currentState;
|
||||
|
||||
@ -292,8 +251,7 @@ protected:
|
||||
virtual void refreshScreen() = 0;
|
||||
|
||||
/**
|
||||
* Save a screenshot of the full display as BMP to the given file. This
|
||||
* uses Common::DumpFile for writing the screenshot.
|
||||
* Saves a screenshot of the entire window, excluding window decorations.
|
||||
*
|
||||
* @param filename The output filename.
|
||||
* @return true on success, false otherwise
|
||||
@ -334,7 +292,6 @@ protected:
|
||||
*/
|
||||
virtual void *getProcAddress(const char *name) const = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Try to determine the internal parameters for a given pixel format.
|
||||
*
|
||||
@ -342,49 +299,9 @@ private:
|
||||
*/
|
||||
bool getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const;
|
||||
|
||||
//
|
||||
// Actual hardware screen
|
||||
//
|
||||
|
||||
/**
|
||||
* The width of the physical output.
|
||||
*/
|
||||
uint _outputScreenWidth;
|
||||
|
||||
/**
|
||||
* The height of the physical output.
|
||||
*/
|
||||
uint _outputScreenHeight;
|
||||
|
||||
/**
|
||||
* @return The desired aspect of the game screen.
|
||||
*/
|
||||
frac_t getDesiredGameScreenAspect() const;
|
||||
|
||||
/**
|
||||
* Recalculates the area used to display the game screen.
|
||||
*/
|
||||
void recalculateDisplayArea();
|
||||
|
||||
/**
|
||||
* The X coordinate of the game screen.
|
||||
*/
|
||||
uint _displayX;
|
||||
|
||||
/**
|
||||
* The Y coordinate of the game screen.
|
||||
*/
|
||||
uint _displayY;
|
||||
|
||||
/**
|
||||
* The width of the game screen in physical coordinates.
|
||||
*/
|
||||
uint _displayWidth;
|
||||
|
||||
/**
|
||||
* The height of the game screen in physical coordinates.
|
||||
*/
|
||||
uint _displayHeight;
|
||||
virtual bool gameNeedsAspectRatioCorrection() const override;
|
||||
virtual void recalculateDisplayAreas() override;
|
||||
virtual void handleResizeImpl(const int width, const int height) override;
|
||||
|
||||
/**
|
||||
* The default pixel format of the backend.
|
||||
@ -396,12 +313,8 @@ private:
|
||||
*/
|
||||
Graphics::PixelFormat _defaultFormatAlpha;
|
||||
|
||||
//
|
||||
// Game screen
|
||||
//
|
||||
|
||||
/**
|
||||
* The virtual game screen.
|
||||
* The rendering surface for the virtual game screen.
|
||||
*/
|
||||
Surface *_gameScreen;
|
||||
|
||||
@ -420,15 +333,10 @@ private:
|
||||
//
|
||||
|
||||
/**
|
||||
* The overlay screen.
|
||||
* The rendering surface for the overlay.
|
||||
*/
|
||||
Surface *_overlay;
|
||||
|
||||
/**
|
||||
* Whether the overlay is visible or not.
|
||||
*/
|
||||
bool _overlayVisible;
|
||||
|
||||
//
|
||||
// Cursor
|
||||
//
|
||||
@ -439,37 +347,17 @@ private:
|
||||
void updateCursorPalette();
|
||||
|
||||
/**
|
||||
* The cursor image.
|
||||
* The rendering surface for the mouse cursor.
|
||||
*/
|
||||
Surface *_cursor;
|
||||
|
||||
/**
|
||||
* X coordinate of the cursor in phyiscal coordinates.
|
||||
*/
|
||||
int _cursorX;
|
||||
|
||||
/**
|
||||
* Y coordinate of the cursor in physical coordinates.
|
||||
*/
|
||||
int _cursorY;
|
||||
|
||||
/**
|
||||
* X coordinate used for drawing the cursor.
|
||||
*/
|
||||
int _cursorDisplayX;
|
||||
|
||||
/**
|
||||
* Y coordinate used for drawing the cursor.
|
||||
*/
|
||||
int _cursorDisplayY;
|
||||
|
||||
/**
|
||||
* The X offset for the cursor hotspot in unscaled coordinates.
|
||||
* The X offset for the cursor hotspot in unscaled game coordinates.
|
||||
*/
|
||||
int _cursorHotspotX;
|
||||
|
||||
/**
|
||||
* The Y offset for the cursor hotspot in unscaled coordinates.
|
||||
* The Y offset for the cursor hotspot in unscaled game coordinates.
|
||||
*/
|
||||
int _cursorHotspotY;
|
||||
|
||||
@ -480,22 +368,24 @@ private:
|
||||
void recalculateCursorScaling();
|
||||
|
||||
/**
|
||||
* The X offset for the cursor hotspot in scaled coordinates.
|
||||
* The X offset for the cursor hotspot in scaled game display area
|
||||
* coordinates.
|
||||
*/
|
||||
int _cursorHotspotXScaled;
|
||||
|
||||
/**
|
||||
* The Y offset for the cursor hotspot in scaled coordinates.
|
||||
* The Y offset for the cursor hotspot in scaled game display area
|
||||
* coordinates.
|
||||
*/
|
||||
int _cursorHotspotYScaled;
|
||||
|
||||
/**
|
||||
* The width of the cursor scaled coordinates.
|
||||
* The width of the cursor in scaled game display area coordinates.
|
||||
*/
|
||||
uint _cursorWidthScaled;
|
||||
|
||||
/**
|
||||
* The height of the cursor scaled coordinates.
|
||||
* The height of the cursor in scaled game display area coordinates.
|
||||
*/
|
||||
uint _cursorHeightScaled;
|
||||
|
||||
@ -504,11 +394,6 @@ private:
|
||||
*/
|
||||
uint32 _cursorKeyColor;
|
||||
|
||||
/**
|
||||
* Whether the cursor is actually visible.
|
||||
*/
|
||||
bool _cursorVisible;
|
||||
|
||||
/**
|
||||
* Whether no cursor scaling should be applied.
|
||||
*/
|
||||
@ -524,15 +409,6 @@ private:
|
||||
*/
|
||||
byte _cursorPalette[3 * 256];
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
/**
|
||||
* Whether the screen contents shall be forced to redrawn.
|
||||
*/
|
||||
bool _forceRedraw;
|
||||
|
||||
#ifdef USE_OSD
|
||||
//
|
||||
// OSD
|
||||
@ -541,7 +417,7 @@ protected:
|
||||
/**
|
||||
* Returns the font used for on screen display
|
||||
*/
|
||||
virtual const Graphics::Font *getFontOSD();
|
||||
virtual const Graphics::Font *getFontOSD() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -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(¤tWidth, ¤tHeight);
|
||||
if (width != (uint)currentWidth || height != (uint)currentHeight)
|
||||
getWindowSizeFromSdl(¤tWidth, ¤tHeight);
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -30,19 +30,19 @@ class PSP2SdlGraphicsManager : public SurfaceSdlGraphicsManager {
|
||||
public:
|
||||
PSP2SdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
|
||||
virtual ~PSP2SdlGraphicsManager();
|
||||
|
||||
virtual OSystem::TransactionError endGFXTransaction();
|
||||
virtual const OSystem::GraphicsMode *getSupportedShaders() const;
|
||||
|
||||
virtual OSystem::TransactionError endGFXTransaction() override;
|
||||
virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
|
||||
|
||||
protected:
|
||||
virtual void setGraphicsModeIntern();
|
||||
virtual void unloadGFXMode();
|
||||
virtual bool hotswapGFXMode();
|
||||
virtual void setGraphicsModeIntern() override;
|
||||
virtual void unloadGFXMode() override;
|
||||
virtual bool hotswapGFXMode() override;
|
||||
|
||||
virtual void internUpdateScreen();
|
||||
virtual void updateShader();
|
||||
virtual void setAspectRatioCorrection(bool enable);
|
||||
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
|
||||
virtual void internUpdateScreen() override;
|
||||
virtual void updateShader() override;
|
||||
virtual void setAspectRatioCorrection(bool enable) override;
|
||||
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) override;
|
||||
void PSP2_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
|
||||
void PSP2_UpdateFiltering();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
|
||||
#define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
|
||||
|
||||
#include "backends/graphics/graphics.h"
|
||||
#include "backends/graphics/windowed.h"
|
||||
#include "backends/platform/sdl/sdl-window.h"
|
||||
|
||||
#include "common/rect.h"
|
||||
@ -32,13 +32,11 @@ class SdlEventSource;
|
||||
|
||||
/**
|
||||
* Base class for a SDL based graphics manager.
|
||||
*
|
||||
* It features a few extra a few extra features required by SdlEventSource.
|
||||
*/
|
||||
class SdlGraphicsManager : virtual public GraphicsManager {
|
||||
class SdlGraphicsManager : virtual public WindowedGraphicsManager {
|
||||
public:
|
||||
SdlGraphicsManager(SdlEventSource *source, SdlWindow *window);
|
||||
virtual ~SdlGraphicsManager();
|
||||
virtual ~SdlGraphicsManager() {}
|
||||
|
||||
/**
|
||||
* Makes this graphics manager active. That means it should be ready to
|
||||
@ -62,10 +60,10 @@ public:
|
||||
virtual void notifyVideoExpose() = 0;
|
||||
|
||||
/**
|
||||
* Notify the graphics manager about an resize event.
|
||||
* Notify the graphics manager about a resize event.
|
||||
*
|
||||
* It is noteworthy that the requested width/height should actually be set
|
||||
* up as is and not changed by the graphics manager, since else it might
|
||||
* up as is and not changed by the graphics manager, since otherwise it may
|
||||
* lead to odd behavior for certain window managers.
|
||||
*
|
||||
* It is only required to overwrite this method in case you want a
|
||||
@ -74,27 +72,28 @@ public:
|
||||
* @param width Requested window width.
|
||||
* @param height Requested window height.
|
||||
*/
|
||||
virtual void notifyResize(const uint width, const uint height) {}
|
||||
virtual void notifyResize(const int width, const int height) {}
|
||||
|
||||
/**
|
||||
* Transforms real screen coordinates into the current active screen
|
||||
* coordinates (may be either game screen or overlay).
|
||||
* Notifies the graphics manager about a mouse position change.
|
||||
*
|
||||
* @param point Mouse coordinates to transform.
|
||||
* The passed point *must* be converted from window coordinates to virtual
|
||||
* coordinates in order for the event to be processed correctly by the game
|
||||
* engine. Just use `convertWindowToVirtual` for this unless you need to do
|
||||
* something special.
|
||||
*
|
||||
* @param mouse The mouse position in window coordinates, which must be
|
||||
* converted synchronously to virtual coordinates.
|
||||
* @returns true if the mouse was in a valid position for the game and
|
||||
* should cause the event to be sent to the game.
|
||||
*/
|
||||
virtual void transformMouseCoordinates(Common::Point &point) = 0;
|
||||
virtual bool notifyMousePosition(Common::Point &mouse);
|
||||
|
||||
/**
|
||||
* Notifies the graphics manager about a position change according to the
|
||||
* real screen coordinates.
|
||||
*
|
||||
* @param mouse Mouse position.
|
||||
*/
|
||||
virtual void notifyMousePos(Common::Point mouse) = 0;
|
||||
virtual bool showMouse(const bool visible) override;
|
||||
|
||||
/**
|
||||
* A (subset) of the graphic manager's state. This is used when switching
|
||||
* between different SDL graphic managers on runtime.
|
||||
* between different SDL graphic managers at runtime.
|
||||
*/
|
||||
struct State {
|
||||
int screenWidth, screenHeight;
|
||||
@ -108,17 +107,17 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Queries the current state of the graphic manager.
|
||||
* Gets the current state of the graphics manager.
|
||||
*/
|
||||
State getState();
|
||||
State getState() const;
|
||||
|
||||
/**
|
||||
* Setup a basic state of the graphic manager.
|
||||
* Sets up a basic state of the graphics manager.
|
||||
*/
|
||||
bool setState(const State &state);
|
||||
|
||||
/**
|
||||
* Queries the SDL window.
|
||||
* @returns the SDL window.
|
||||
*/
|
||||
SdlWindow *getWindow() const { return _window; }
|
||||
|
||||
@ -130,6 +129,31 @@ protected:
|
||||
bool defaultGraphicsModeConfig() const;
|
||||
int getGraphicsModeIdByName(const Common::String &name) const;
|
||||
|
||||
/**
|
||||
* Gets the dimensions of the window directly from SDL instead of from the
|
||||
* values stored by the graphics manager.
|
||||
*/
|
||||
void getWindowSizeFromSdl(int *width, int *height) const {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
assert(_window);
|
||||
SDL_GetWindowSize(_window->getSDLWindow(), width, height);
|
||||
#else
|
||||
assert(_hwScreen);
|
||||
|
||||
if (width) {
|
||||
*width = _hwScreen->w;
|
||||
}
|
||||
|
||||
if (height) {
|
||||
*height = _hwScreen->h;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void setSystemMousePosition(const int x, const int y) override;
|
||||
|
||||
virtual void handleResizeImpl(const int width, const int height) override;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
public:
|
||||
void unlockWindowSize() {
|
||||
@ -146,6 +170,7 @@ protected:
|
||||
bool createOrUpdateWindow(const int width, const int height, const Uint32 flags);
|
||||
#endif
|
||||
|
||||
SDL_Surface *_hwScreen;
|
||||
SdlEventSource *_eventSource;
|
||||
SdlWindow *_window;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,17 +39,7 @@
|
||||
#define USE_SDL_DEBUG_FOCUSRECT
|
||||
#endif
|
||||
|
||||
// We have (some) support for resizable windows when SDL2 is used. However
|
||||
// the overlay still uses the resolution setup with SDL_SetVideoMode. This
|
||||
// makes the GUI look subpar when the user resizes the window. In addition
|
||||
// we do not adapt the scale factor right now. Thus, we disable this code
|
||||
// path for now.
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0) && 0
|
||||
#define USE_SDL_RESIZABLE_WINDOW
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
|
||||
// Uncomment this to enable the 'on screen display' code.
|
||||
#define USE_OSD 1
|
||||
#endif
|
||||
|
||||
@ -89,76 +79,70 @@ public:
|
||||
SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
|
||||
virtual ~SurfaceSdlGraphicsManager();
|
||||
|
||||
virtual void activateManager();
|
||||
virtual void deactivateManager();
|
||||
virtual void activateManager() override;
|
||||
virtual void deactivateManager() override;
|
||||
|
||||
virtual bool hasFeature(OSystem::Feature f);
|
||||
virtual void setFeatureState(OSystem::Feature f, bool enable);
|
||||
virtual bool getFeatureState(OSystem::Feature f);
|
||||
virtual bool hasFeature(OSystem::Feature f) const override;
|
||||
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
|
||||
virtual bool getFeatureState(OSystem::Feature f) const override;
|
||||
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
|
||||
virtual int getDefaultGraphicsMode() const;
|
||||
virtual bool setGraphicsMode(int mode);
|
||||
virtual int getGraphicsMode() const;
|
||||
virtual void resetGraphicsScale();
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
|
||||
virtual int getDefaultGraphicsMode() const override;
|
||||
virtual bool setGraphicsMode(int mode) override;
|
||||
virtual int getGraphicsMode() const override;
|
||||
virtual void resetGraphicsScale() override;
|
||||
#ifdef USE_RGB_COLOR
|
||||
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
|
||||
virtual Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
|
||||
#endif
|
||||
virtual const OSystem::GraphicsMode *getSupportedShaders() const;
|
||||
virtual int getShader() const;
|
||||
virtual bool setShader(int id);
|
||||
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
|
||||
virtual int getScreenChangeID() const { return _screenChangeCount; }
|
||||
virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
|
||||
virtual int getShader() const override;
|
||||
virtual bool setShader(int id) override;
|
||||
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
|
||||
virtual int getScreenChangeID() const override { return _screenChangeCount; }
|
||||
|
||||
virtual void beginGFXTransaction();
|
||||
virtual OSystem::TransactionError endGFXTransaction();
|
||||
virtual void beginGFXTransaction() override;
|
||||
virtual OSystem::TransactionError endGFXTransaction() override;
|
||||
|
||||
virtual int16 getHeight();
|
||||
virtual int16 getWidth();
|
||||
virtual int16 getHeight() const override;
|
||||
virtual int16 getWidth() const override;
|
||||
|
||||
protected:
|
||||
// PaletteManager API
|
||||
virtual void setPalette(const byte *colors, uint start, uint num);
|
||||
virtual void grabPalette(byte *colors, uint start, uint num);
|
||||
virtual void setPalette(const byte *colors, uint start, uint num) override;
|
||||
virtual void grabPalette(byte *colors, uint start, uint num) const override;
|
||||
|
||||
public:
|
||||
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual Graphics::Surface *lockScreen();
|
||||
virtual void unlockScreen();
|
||||
virtual void fillScreen(uint32 col);
|
||||
virtual void updateScreen();
|
||||
virtual void setShakePos(int shakeOffset);
|
||||
virtual void setFocusRectangle(const Common::Rect& rect);
|
||||
virtual void clearFocusRectangle();
|
||||
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
|
||||
virtual Graphics::Surface *lockScreen() override;
|
||||
virtual void unlockScreen() override;
|
||||
virtual void fillScreen(uint32 col) override;
|
||||
virtual void updateScreen() override;
|
||||
virtual void setShakePos(int shakeOffset) override;
|
||||
virtual void setFocusRectangle(const Common::Rect& rect) override;
|
||||
virtual void clearFocusRectangle() override;
|
||||
|
||||
virtual void showOverlay();
|
||||
virtual void hideOverlay();
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
|
||||
virtual void clearOverlay();
|
||||
virtual void grabOverlay(void *buf, int pitch);
|
||||
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual int16 getOverlayHeight() { return _videoMode.overlayHeight; }
|
||||
virtual int16 getOverlayWidth() { return _videoMode.overlayWidth; }
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
|
||||
virtual void clearOverlay() override;
|
||||
virtual void grabOverlay(void *buf, int pitch) const override;
|
||||
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
|
||||
virtual int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
|
||||
virtual int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
|
||||
|
||||
virtual bool showMouse(bool visible);
|
||||
virtual void warpMouse(int x, int y);
|
||||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override;
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
|
||||
|
||||
#ifdef USE_OSD
|
||||
virtual void displayMessageOnOSD(const char *msg);
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
|
||||
virtual void displayMessageOnOSD(const char *msg) override;
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
|
||||
#endif
|
||||
|
||||
// Override from Common::EventObserver
|
||||
bool notifyEvent(const Common::Event &event);
|
||||
virtual bool notifyEvent(const Common::Event &event) override;
|
||||
|
||||
// SdlGraphicsManager interface
|
||||
virtual void notifyVideoExpose();
|
||||
virtual void notifyResize(const uint width, const uint height);
|
||||
virtual void transformMouseCoordinates(Common::Point &point);
|
||||
virtual void notifyMousePos(Common::Point mouse);
|
||||
virtual void notifyVideoExpose() override;
|
||||
virtual void notifyResize(const int width, const int height) override;
|
||||
|
||||
protected:
|
||||
#ifdef USE_OSD
|
||||
@ -187,8 +171,11 @@ protected:
|
||||
void drawOSD();
|
||||
#endif
|
||||
|
||||
/** Hardware screen */
|
||||
SDL_Surface *_hwscreen;
|
||||
virtual bool gameNeedsAspectRatioCorrection() const override {
|
||||
return _videoMode.aspectRatioCorrection;
|
||||
}
|
||||
|
||||
virtual void handleResizeImpl(const int width, const int height) override;
|
||||
|
||||
virtual int getGraphicsModeScale(int mode) const override;
|
||||
|
||||
@ -197,10 +184,7 @@ protected:
|
||||
* around this API to keep the code paths as close as possible. */
|
||||
SDL_Renderer *_renderer;
|
||||
SDL_Texture *_screenTexture;
|
||||
SDL_Rect _viewport;
|
||||
int _windowWidth, _windowHeight;
|
||||
void deinitializeRenderer();
|
||||
void setWindowResolution(int width, int height);
|
||||
void recreateScreenTexture();
|
||||
|
||||
virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
|
||||
@ -209,9 +193,9 @@ protected:
|
||||
|
||||
/** Unseen game screen */
|
||||
SDL_Surface *_screen;
|
||||
#ifdef USE_RGB_COLOR
|
||||
Graphics::PixelFormat _screenFormat;
|
||||
Graphics::PixelFormat _cursorFormat;
|
||||
#ifdef USE_RGB_COLOR
|
||||
Common::List<Graphics::PixelFormat> _supportedFormats;
|
||||
|
||||
/**
|
||||
@ -227,7 +211,6 @@ protected:
|
||||
SDL_Surface *_tmpscreen2;
|
||||
|
||||
SDL_Surface *_overlayscreen;
|
||||
bool _overlayVisible;
|
||||
Graphics::PixelFormat _overlayFormat;
|
||||
|
||||
enum {
|
||||
@ -289,14 +272,11 @@ protected:
|
||||
uint8 _originalBitsPerPixel;
|
||||
#endif
|
||||
|
||||
/** Force full redraw on next updateScreen */
|
||||
bool _forceFull;
|
||||
|
||||
ScalerProc *_scalerProc;
|
||||
int _scalerType;
|
||||
int _transactionMode;
|
||||
|
||||
// Indicates whether it is needed to free _hwsurface in destructor
|
||||
// Indicates whether it is needed to free _hwSurface in destructor
|
||||
bool _displayDisabled;
|
||||
|
||||
bool _screenIsLocked;
|
||||
@ -317,10 +297,6 @@ protected:
|
||||
int _numDirtyRects;
|
||||
|
||||
struct MousePos {
|
||||
// The mouse position, using either virtual (game) or real
|
||||
// (overlay) coordinates.
|
||||
int16 x, y;
|
||||
|
||||
// The size and hotspot of the original cursor image.
|
||||
int16 w, h;
|
||||
int16 hotX, hotY;
|
||||
@ -335,14 +311,12 @@ protected:
|
||||
int16 vW, vH;
|
||||
int16 vHotX, vHotY;
|
||||
|
||||
MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
|
||||
MousePos() : w(0), h(0), hotX(0), hotY(0),
|
||||
rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
|
||||
vHotX(0), vHotY(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
bool _mouseVisible;
|
||||
bool _mouseNeedsRedraw;
|
||||
byte *_mouseData;
|
||||
SDL_Rect _mouseBackup;
|
||||
MousePos _mouseCurState;
|
||||
@ -395,21 +369,45 @@ protected:
|
||||
virtual void unloadGFXMode();
|
||||
virtual bool hotswapGFXMode();
|
||||
|
||||
virtual void setFullscreenMode(bool enable);
|
||||
virtual void setAspectRatioCorrection(bool enable);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
virtual void setFilteringMode(bool enable);
|
||||
void setFilteringMode(bool enable);
|
||||
#endif
|
||||
|
||||
virtual int effectiveScreenHeight() const;
|
||||
|
||||
virtual bool saveScreenshot(const char *filename);
|
||||
virtual void setGraphicsModeIntern();
|
||||
|
||||
virtual bool handleScalerHotkeys(Common::KeyCode key);
|
||||
virtual bool isScalerHotkey(const Common::Event &event);
|
||||
virtual void setMousePos(int x, int y);
|
||||
virtual void toggleFullScreen();
|
||||
virtual bool saveScreenshot(const char *filename);
|
||||
private:
|
||||
void setFullscreenMode(bool enable);
|
||||
bool handleScalerHotkeys(Common::KeyCode key);
|
||||
bool isScalerHotkey(const Common::Event &event);
|
||||
void toggleFullScreen();
|
||||
|
||||
/**
|
||||
* Converts the given point from the overlay's coordinate space to the
|
||||
* game's coordinate space.
|
||||
*/
|
||||
Common::Point convertOverlayToGame(const int x, const int y) const {
|
||||
if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
|
||||
error("convertOverlayToGame called without a valid overlay");
|
||||
}
|
||||
|
||||
return Common::Point(x * getWidth() / getOverlayWidth(),
|
||||
y * getHeight() / getOverlayHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given point from the game's coordinate space to the
|
||||
* overlay's coordinate space.
|
||||
*/
|
||||
Common::Point convertGameToOverlay(const int x, const int y) const {
|
||||
if (getWidth() == 0 || getHeight() == 0) {
|
||||
error("convertGameToOverlay called without a valid overlay");
|
||||
}
|
||||
|
||||
return Common::Point(x * getOverlayWidth() / getWidth(),
|
||||
y * getOverlayHeight() / getHeight());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
337
backends/graphics/windowed.h
Normal file
337
backends/graphics/windowed.h
Normal file
@ -0,0 +1,337 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_GRAPHICS_WINDOWED_H
|
||||
#define BACKENDS_GRAPHICS_WINDOWED_H
|
||||
|
||||
#include "backends/graphics/graphics.h"
|
||||
#include "common/frac.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "graphics/scaler/aspect.h"
|
||||
|
||||
class WindowedGraphicsManager : virtual public GraphicsManager {
|
||||
public:
|
||||
WindowedGraphicsManager() :
|
||||
_windowWidth(0),
|
||||
_windowHeight(0),
|
||||
_overlayVisible(false),
|
||||
_forceRedraw(false),
|
||||
_cursorVisible(false),
|
||||
_cursorX(0),
|
||||
_cursorY(0),
|
||||
_cursorNeedsRedraw(false),
|
||||
_cursorLastInActiveArea(true) {}
|
||||
|
||||
virtual void showOverlay() override {
|
||||
if (_overlayVisible)
|
||||
return;
|
||||
|
||||
_activeArea.drawRect = _overlayDrawRect;
|
||||
_activeArea.width = getOverlayWidth();
|
||||
_activeArea.height = getOverlayHeight();
|
||||
_overlayVisible = true;
|
||||
_forceRedraw = true;
|
||||
}
|
||||
|
||||
virtual void hideOverlay() override {
|
||||
if (!_overlayVisible)
|
||||
return;
|
||||
|
||||
_activeArea.drawRect = _gameDrawRect;
|
||||
_activeArea.width = getWidth();
|
||||
_activeArea.height = getHeight();
|
||||
_overlayVisible = false;
|
||||
_forceRedraw = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @returns whether or not the game screen must have aspect ratio correction
|
||||
* applied for correct rendering.
|
||||
*/
|
||||
virtual bool gameNeedsAspectRatioCorrection() const = 0;
|
||||
|
||||
/**
|
||||
* Backend-specific implementation for updating internal surfaces that need
|
||||
* to reflect the new window size.
|
||||
*/
|
||||
virtual void handleResizeImpl(const int width, const int height) = 0;
|
||||
|
||||
/**
|
||||
* Converts the given point from the active virtual screen's coordinate
|
||||
* space to the window's coordinate space (i.e. game-to-window or
|
||||
* overlay-to-window).
|
||||
*/
|
||||
Common::Point convertVirtualToWindow(const int x, const int y) const {
|
||||
const int targetX = _activeArea.drawRect.left;
|
||||
const int targetY = _activeArea.drawRect.top;
|
||||
const int targetWidth = _activeArea.drawRect.width();
|
||||
const int targetHeight = _activeArea.drawRect.height();
|
||||
const int sourceWidth = _activeArea.width;
|
||||
const int sourceHeight = _activeArea.height;
|
||||
|
||||
if (sourceWidth == 0 || sourceHeight == 0) {
|
||||
error("convertVirtualToWindow called without a valid draw rect");
|
||||
}
|
||||
|
||||
return Common::Point(targetX + x * targetWidth / sourceWidth,
|
||||
targetY + y * targetHeight / sourceHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given point from the window's coordinate space to the
|
||||
* active virtual screen's coordinate space (i.e. window-to-game or
|
||||
* window-to-overlay).
|
||||
*/
|
||||
Common::Point convertWindowToVirtual(int x, int y) const {
|
||||
const int sourceX = _activeArea.drawRect.left;
|
||||
const int sourceY = _activeArea.drawRect.top;
|
||||
const int sourceMaxX = _activeArea.drawRect.right - 1;
|
||||
const int sourceMaxY = _activeArea.drawRect.bottom - 1;
|
||||
const int sourceWidth = _activeArea.drawRect.width();
|
||||
const int sourceHeight = _activeArea.drawRect.height();
|
||||
const int targetWidth = _activeArea.width;
|
||||
const int targetHeight = _activeArea.height;
|
||||
|
||||
if (sourceWidth == 0 || sourceHeight == 0) {
|
||||
error("convertWindowToVirtual called without a valid draw rect");
|
||||
}
|
||||
|
||||
x = CLIP<int>(x, sourceX, sourceMaxX);
|
||||
y = CLIP<int>(y, sourceY, sourceMaxY);
|
||||
|
||||
return Common::Point(((x - sourceX) * targetWidth) / sourceWidth,
|
||||
((y - sourceY) * targetHeight) / sourceHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the desired aspect ratio of the game surface.
|
||||
*/
|
||||
frac_t getDesiredGameAspectRatio() const {
|
||||
if (getHeight() == 0 || gameNeedsAspectRatioCorrection()) {
|
||||
return intToFrac(4) / 3;
|
||||
}
|
||||
|
||||
return intToFrac(getWidth()) / getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the window has been updated with new dimensions.
|
||||
*
|
||||
* @param width The new width of the window, excluding window decoration.
|
||||
* @param height The new height of the window, excluding window decoration.
|
||||
*/
|
||||
void handleResize(const int width, const int height) {
|
||||
_windowWidth = width;
|
||||
_windowHeight = height;
|
||||
handleResizeImpl(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the display areas for the game and overlay surfaces within
|
||||
* the window.
|
||||
*/
|
||||
virtual void recalculateDisplayAreas() {
|
||||
if (_windowHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
|
||||
|
||||
populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), outputAspect, _gameDrawRect);
|
||||
|
||||
if (getOverlayHeight()) {
|
||||
const frac_t overlayAspect = intToFrac(getOverlayWidth()) / getOverlayHeight();
|
||||
populateDisplayAreaDrawRect(overlayAspect, outputAspect, _overlayDrawRect);
|
||||
}
|
||||
|
||||
if (_overlayVisible) {
|
||||
_activeArea.drawRect = _overlayDrawRect;
|
||||
_activeArea.width = getOverlayWidth();
|
||||
_activeArea.height = getOverlayHeight();
|
||||
} else {
|
||||
_activeArea.drawRect = _gameDrawRect;
|
||||
_activeArea.width = getWidth();
|
||||
_activeArea.height = getHeight();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the position of the hardware mouse cursor in the host system,
|
||||
* relative to the window.
|
||||
*
|
||||
* @param x X coordinate in window coordinates.
|
||||
* @param y Y coordinate in window coordinates.
|
||||
*/
|
||||
virtual void setSystemMousePosition(const int x, const int y) = 0;
|
||||
|
||||
virtual bool showMouse(const bool visible) override {
|
||||
if (_cursorVisible == visible) {
|
||||
return visible;
|
||||
}
|
||||
|
||||
const bool last = _cursorVisible;
|
||||
_cursorVisible = visible;
|
||||
_cursorNeedsRedraw = true;
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move ("warp") the mouse cursor to the specified position.
|
||||
*
|
||||
* @param x The new X position of the mouse in virtual screen coordinates.
|
||||
* @param y The new Y position of the mouse in virtual screen coordinates.
|
||||
*/
|
||||
void warpMouse(const int x, const int y) {
|
||||
// Check active coordinate instead of window coordinate to avoid warping
|
||||
// the mouse if it is still within the same virtual pixel
|
||||
const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
|
||||
if (virtualCursor.x != x || virtualCursor.y != y) {
|
||||
// Warping the mouse in SDL generates a mouse movement event, so
|
||||
// `setMousePosition` would be called eventually through the
|
||||
// `notifyMousePosition` callback if we *only* set the system mouse
|
||||
// position here. However, this can cause problems with some games.
|
||||
// For example, the cannon script in CoMI calls to warp the mouse
|
||||
// twice each time the cannon is reloaded, and unless we update the
|
||||
// mouse position immediately, the second call is ignored, which
|
||||
// causes the cannon to change its aim.
|
||||
const Common::Point windowCursor = convertVirtualToWindow(x, y);
|
||||
setMousePosition(windowCursor.x, windowCursor.y);
|
||||
setSystemMousePosition(windowCursor.x, windowCursor.y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the rendered mouse cursor in the window.
|
||||
*
|
||||
* @param x X coordinate in window coordinates.
|
||||
* @param y Y coordinate in window coordinates.
|
||||
*/
|
||||
void setMousePosition(int x, int y) {
|
||||
if (_cursorX != x || _cursorY != y) {
|
||||
_cursorNeedsRedraw = true;
|
||||
}
|
||||
|
||||
_cursorX = x;
|
||||
_cursorY = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the window, excluding window decoration.
|
||||
*/
|
||||
int _windowWidth;
|
||||
|
||||
/**
|
||||
* The height of the window, excluding window decoration.
|
||||
*/
|
||||
int _windowHeight;
|
||||
|
||||
/**
|
||||
* Whether the overlay (i.e. launcher, including the out-of-game launcher)
|
||||
* is visible or not.
|
||||
*/
|
||||
bool _overlayVisible;
|
||||
|
||||
/**
|
||||
* The scaled draw rectangle for the game surface within the window.
|
||||
*/
|
||||
Common::Rect _gameDrawRect;
|
||||
|
||||
/**
|
||||
* The scaled draw rectangle for the overlay (launcher) surface within the
|
||||
* window.
|
||||
*/
|
||||
Common::Rect _overlayDrawRect;
|
||||
|
||||
/**
|
||||
* Data about the display area of a virtual screen.
|
||||
*/
|
||||
struct DisplayArea {
|
||||
/**
|
||||
* The scaled area where the virtual screen is drawn within the window.
|
||||
*/
|
||||
Common::Rect drawRect;
|
||||
|
||||
/**
|
||||
* The width of the virtual screen's unscaled coordinate space.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* The height of the virtual screen's unscaled coordinate space.
|
||||
*/
|
||||
int height;
|
||||
};
|
||||
|
||||
/**
|
||||
* Display area information about the currently active virtual screen. This
|
||||
* will be the overlay screen when the overlay is active, and the game
|
||||
* screen otherwise.
|
||||
*/
|
||||
DisplayArea _activeArea;
|
||||
|
||||
/**
|
||||
* Whether the screen must be redrawn on the next frame.
|
||||
*/
|
||||
bool _forceRedraw;
|
||||
|
||||
/**
|
||||
* Whether the cursor is actually visible.
|
||||
*/
|
||||
bool _cursorVisible;
|
||||
|
||||
/**
|
||||
* Whether the mouse cursor needs to be redrawn on the next frame.
|
||||
*/
|
||||
bool _cursorNeedsRedraw;
|
||||
|
||||
/**
|
||||
* Whether the last position of the system cursor was within the active area
|
||||
* of the window.
|
||||
*/
|
||||
bool _cursorLastInActiveArea;
|
||||
|
||||
/**
|
||||
* The position of the mouse cursor, in window coordinates.
|
||||
*/
|
||||
int _cursorX, _cursorY;
|
||||
|
||||
private:
|
||||
void populateDisplayAreaDrawRect(const frac_t inputAspect, const frac_t outputAspect, Common::Rect &drawRect) const {
|
||||
int width = _windowWidth;
|
||||
int height = _windowHeight;
|
||||
|
||||
// Maintain aspect ratios
|
||||
if (outputAspect < inputAspect) {
|
||||
height = intToFrac(width) / inputAspect;
|
||||
} else if (outputAspect > inputAspect) {
|
||||
width = fracToInt(height * inputAspect);
|
||||
}
|
||||
|
||||
drawRect.left = (_windowWidth - width) / 2;
|
||||
drawRect.top = (_windowHeight - height) / 2;
|
||||
drawRect.setWidth(width);
|
||||
drawRect.setHeight(height);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -217,6 +217,7 @@ bool ModularBackend::showMouse(bool visible) {
|
||||
}
|
||||
|
||||
void ModularBackend::warpMouse(int x, int y) {
|
||||
_eventManager->purgeMouseEvents();
|
||||
_graphicsManager->warpMouse(x, y);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user