ALL: Replace cursorTargetScale in OSystem API with a simple "do not scale" logic.
All uses of the old target scale API actually wanted to disallow scaling of the mouse cursor. This commit adapts our API to this and thus simplifies backend implementations. Some backends, most notable the Wii and Android, did some implementation of the cursor target scale, which I didn't adapt yet. I added a TODO for the porters there.
This commit is contained in:
parent
db77b9e4a7
commit
a401f0a19e
45 changed files with 1086 additions and 1108 deletions
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
virtual bool showMouse(bool visible) = 0;
|
virtual bool showMouse(bool visible) = 0;
|
||||||
virtual void warpMouse(int x, int y) = 0;
|
virtual void warpMouse(int x, int y) = 0;
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0;
|
||||||
virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0;
|
virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0;
|
||||||
|
|
||||||
virtual void displayMessageOnOSD(const char *msg) {}
|
virtual void displayMessageOnOSD(const char *msg) {}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
|
|
||||||
bool showMouse(bool visible) { return !visible; }
|
bool showMouse(bool visible) { return !visible; }
|
||||||
void warpMouse(int x, int y) {}
|
void warpMouse(int x, int y) {}
|
||||||
void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) {}
|
void setMouseCursor(const byte *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) {}
|
void setCursorPalette(const byte *colors, uint start, uint num) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
|
||||||
_transactionMode(kTransactionNone),
|
_transactionMode(kTransactionNone),
|
||||||
_cursorNeedsRedraw(false), _cursorPaletteDisabled(true),
|
_cursorNeedsRedraw(false), _cursorPaletteDisabled(true),
|
||||||
_cursorVisible(false), _cursorKeyColor(0),
|
_cursorVisible(false), _cursorKeyColor(0),
|
||||||
_cursorTargetScale(1),
|
_cursorDontScale(false),
|
||||||
_formatBGR(false),
|
_formatBGR(false),
|
||||||
_displayX(0), _displayY(0), _displayWidth(0), _displayHeight(0) {
|
_displayX(0), _displayY(0), _displayWidth(0), _displayHeight(0) {
|
||||||
|
|
||||||
|
@ -591,7 +591,7 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) {
|
||||||
setInternalMousePosition(scaledX, scaledY);
|
setInternalMousePosition(scaledX, scaledY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
#ifdef USE_RGB_COLOR
|
#ifdef USE_RGB_COLOR
|
||||||
if (format)
|
if (format)
|
||||||
_cursorFormat = *format;
|
_cursorFormat = *format;
|
||||||
|
@ -616,7 +616,7 @@ void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int
|
||||||
_cursorState.hotX = hotspotX;
|
_cursorState.hotX = hotspotX;
|
||||||
_cursorState.hotY = hotspotY;
|
_cursorState.hotY = hotspotY;
|
||||||
_cursorKeyColor = keycolor;
|
_cursorKeyColor = keycolor;
|
||||||
_cursorTargetScale = cursorTargetScale;
|
_cursorDontScale = dontScale;
|
||||||
_cursorNeedsRedraw = true;
|
_cursorNeedsRedraw = true;
|
||||||
|
|
||||||
refreshCursorScale();
|
refreshCursorScale();
|
||||||
|
@ -829,28 +829,19 @@ void OpenGLGraphicsManager::refreshCursor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLGraphicsManager::refreshCursorScale() {
|
void OpenGLGraphicsManager::refreshCursorScale() {
|
||||||
// Calculate the scale factors of the screen. We limit ourselves to 3 at
|
// Calculate the scale factors of the screen.
|
||||||
// most here to avoid really big (and ugly) cursors for big resolutions.
|
|
||||||
// It might be noteworthy that 3 is the (current) target scale for the
|
|
||||||
// modern theme and thus assures the cursor is *never* scaled.
|
|
||||||
// We also totally ignore the aspect of the overlay cursor, since aspect
|
// We also totally ignore the aspect of the overlay cursor, since aspect
|
||||||
// ratio correction only applies to the game screen.
|
// ratio correction only applies to the game screen.
|
||||||
uint screenScaleFactorX = MIN(30000, _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth);
|
// TODO: It might make sense to always ignore scaling of the mouse cursor
|
||||||
uint screenScaleFactorY = MIN(30000, _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight);
|
// when the overlay is visible.
|
||||||
|
uint screenScaleFactorX = _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth;
|
||||||
|
uint screenScaleFactorY = _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight;
|
||||||
|
|
||||||
// Apply the target scale factor to the cursor.
|
// Ignore scaling when the cursor should not be scaled.
|
||||||
// It might be noteworthy we only apply any scaling to the cursor in case
|
if (_cursorDontScale) {
|
||||||
// the current scale factor is bigger than the target scale to match
|
|
||||||
// SurfaceSdlGraphicsManager's behavior. Otherwise we would downscale the
|
|
||||||
// GUI cursor of the modern theme for example.
|
|
||||||
if (screenScaleFactorX > uint(_cursorTargetScale * 10000))
|
|
||||||
screenScaleFactorX /= _cursorTargetScale;
|
|
||||||
else
|
|
||||||
screenScaleFactorX = 10000;
|
screenScaleFactorX = 10000;
|
||||||
if (screenScaleFactorY > uint(_cursorTargetScale * 10000))
|
|
||||||
screenScaleFactorY /= _cursorTargetScale;
|
|
||||||
else
|
|
||||||
screenScaleFactorY = 10000;
|
screenScaleFactorY = 10000;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply them (without any possible) aspect ratio correction to the
|
// Apply them (without any possible) aspect ratio correction to the
|
||||||
// overlay.
|
// overlay.
|
||||||
|
@ -859,16 +850,19 @@ void OpenGLGraphicsManager::refreshCursorScale() {
|
||||||
_cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
|
_cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
|
||||||
_cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
|
_cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
|
||||||
|
|
||||||
// Make sure we properly scale the cursor according to the desired aspect.
|
// Only apply scaling when it's desired.
|
||||||
// It might be noteworthy that, unlike with the overlay, we do not limit
|
if (_cursorDontScale) {
|
||||||
// the scale factor here to avoid odd looks if the game uses items as
|
screenScaleFactorX = 10000;
|
||||||
// mouse cursor, which would otherwise suddenly be smaller.
|
screenScaleFactorY = 10000;
|
||||||
int width, height;
|
} else {
|
||||||
calculateDisplaySize(width, height);
|
// Make sure we properly scale the cursor according to the desired aspect.
|
||||||
screenScaleFactorX = (width * 10000 / _videoMode.screenWidth) / _cursorTargetScale;
|
int width, height;
|
||||||
screenScaleFactorY = (height * 10000 / _videoMode.screenHeight) / _cursorTargetScale;
|
calculateDisplaySize(width, height);
|
||||||
|
screenScaleFactorX = (width * 10000 / _videoMode.screenWidth);
|
||||||
|
screenScaleFactorY = (height * 10000 / _videoMode.screenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
// Always scale the cursor for the game.
|
// Apply the scale cursor scaling for the game screen.
|
||||||
_cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
|
_cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
|
||||||
_cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
|
_cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
|
||||||
_cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
|
_cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
|
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
|
virtual void setMouseCursor(const byte *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 setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
virtual void displayMessageOnOSD(const char *msg);
|
virtual void displayMessageOnOSD(const char *msg);
|
||||||
|
@ -283,7 +283,7 @@ protected:
|
||||||
MousePos _cursorState;
|
MousePos _cursorState;
|
||||||
bool _cursorVisible;
|
bool _cursorVisible;
|
||||||
uint32 _cursorKeyColor;
|
uint32 _cursorKeyColor;
|
||||||
int _cursorTargetScale;
|
bool _cursorDontScale;
|
||||||
bool _cursorNeedsRedraw;
|
bool _cursorNeedsRedraw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -63,17 +63,12 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
|
||||||
|
|
||||||
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres")
|
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres")
|
||||||
|
|
||||||
// Table of relative scalers magnitudes
|
// Table of the cursor scalers [scaleFactor - 1]
|
||||||
// [definedScale - 1][scaleFactor - 1]
|
static ScalerProc *scalersMagn[3] = {
|
||||||
static ScalerProc *scalersMagn[3][3] = {
|
|
||||||
#ifdef USE_SCALERS
|
#ifdef USE_SCALERS
|
||||||
{ Normal1x, AdvMame2x, AdvMame3x },
|
Normal1x, AdvMame2x, AdvMame3x
|
||||||
{ Normal1x, Normal1x, Normal1o5x },
|
|
||||||
{ Normal1x, Normal1x, Normal1x }
|
|
||||||
#else // remove dependencies on other scalers
|
#else // remove dependencies on other scalers
|
||||||
{ Normal1x, Normal1x, Normal1x },
|
Normal1x, Normal1x, Normal1x
|
||||||
{ Normal1x, Normal1x, Normal1x },
|
|
||||||
{ Normal1x, Normal1x, Normal1x }
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,7 +130,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
|
||||||
_overlayscreen(0), _tmpscreen2(0),
|
_overlayscreen(0), _tmpscreen2(0),
|
||||||
_scalerProc(0), _screenChangeCount(0),
|
_scalerProc(0), _screenChangeCount(0),
|
||||||
_mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
|
_mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
|
||||||
_mouseOrigSurface(0), _cursorTargetScale(1), _cursorPaletteDisabled(true),
|
_mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
|
||||||
_currentShakePos(0), _newShakePos(0),
|
_currentShakePos(0), _newShakePos(0),
|
||||||
_paletteDirtyStart(0), _paletteDirtyEnd(0),
|
_paletteDirtyStart(0), _paletteDirtyEnd(0),
|
||||||
_screenIsLocked(false),
|
_screenIsLocked(false),
|
||||||
|
@ -1718,7 +1713,7 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
#ifdef USE_RGB_COLOR
|
#ifdef USE_RGB_COLOR
|
||||||
if (!format)
|
if (!format)
|
||||||
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
|
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
|
||||||
|
@ -1739,7 +1734,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h,
|
||||||
|
|
||||||
_mouseKeyColor = keycolor;
|
_mouseKeyColor = keycolor;
|
||||||
|
|
||||||
_cursorTargetScale = cursorTargetScale;
|
_cursorDontScale = dontScale;
|
||||||
|
|
||||||
if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
|
if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
|
||||||
_mouseCurState.w = w;
|
_mouseCurState.w = w;
|
||||||
|
@ -1847,51 +1842,34 @@ void SurfaceSdlGraphicsManager::blitCursor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int rW, rH;
|
int rW, rH;
|
||||||
|
int cursorScale;
|
||||||
|
|
||||||
if (_cursorTargetScale >= _videoMode.scaleFactor) {
|
if (_cursorDontScale) {
|
||||||
// The cursor target scale is greater or equal to the scale at
|
// Don't scale the cursor at all if the user requests this behavior.
|
||||||
// which the rest of the screen is drawn. We do not downscale
|
cursorScale = 1;
|
||||||
// the cursor image, we draw it at its original size. It will
|
|
||||||
// appear too large on screen.
|
|
||||||
|
|
||||||
rW = w;
|
|
||||||
rH = h;
|
|
||||||
_mouseCurState.rHotX = _mouseCurState.hotX;
|
|
||||||
_mouseCurState.rHotY = _mouseCurState.hotY;
|
|
||||||
|
|
||||||
// The virtual dimensions may be larger than the original.
|
|
||||||
|
|
||||||
_mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor;
|
|
||||||
_mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor;
|
|
||||||
_mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
|
|
||||||
_videoMode.scaleFactor;
|
|
||||||
_mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
|
|
||||||
_videoMode.scaleFactor;
|
|
||||||
} else {
|
} else {
|
||||||
// The cursor target scale is smaller than the scale at which
|
// Scale the cursor with the game screen scale factor.
|
||||||
// the rest of the screen is drawn. We scale up the cursor
|
cursorScale = _videoMode.scaleFactor;
|
||||||
// image to make it appear correct.
|
|
||||||
|
|
||||||
rW = w * _videoMode.scaleFactor / _cursorTargetScale;
|
|
||||||
rH = h * _videoMode.scaleFactor / _cursorTargetScale;
|
|
||||||
_mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor /
|
|
||||||
_cursorTargetScale;
|
|
||||||
_mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor /
|
|
||||||
_cursorTargetScale;
|
|
||||||
|
|
||||||
// The virtual dimensions will be the same as the original.
|
|
||||||
|
|
||||||
_mouseCurState.vW = w;
|
|
||||||
_mouseCurState.vH = h;
|
|
||||||
_mouseCurState.vHotX = _mouseCurState.hotX;
|
|
||||||
_mouseCurState.vHotY = _mouseCurState.hotY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adapt the real hotspot according to the scale factor.
|
||||||
|
rW = w * cursorScale;
|
||||||
|
rH = h * cursorScale;
|
||||||
|
_mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
|
||||||
|
_mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
|
||||||
|
|
||||||
|
// The virtual dimensions will be the same as the original.
|
||||||
|
|
||||||
|
_mouseCurState.vW = w;
|
||||||
|
_mouseCurState.vH = h;
|
||||||
|
_mouseCurState.vHotX = _mouseCurState.hotX;
|
||||||
|
_mouseCurState.vHotY = _mouseCurState.hotY;
|
||||||
|
|
||||||
#ifdef USE_SCALERS
|
#ifdef USE_SCALERS
|
||||||
int rH1 = rH; // store original to pass to aspect-correction function later
|
int rH1 = rH; // store original to pass to aspect-correction function later
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) {
|
if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
|
||||||
rH = real2Aspect(rH - 1) + 1;
|
rH = real2Aspect(rH - 1) + 1;
|
||||||
_mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
|
_mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
|
||||||
}
|
}
|
||||||
|
@ -1922,21 +1900,25 @@ void SurfaceSdlGraphicsManager::blitCursor() {
|
||||||
|
|
||||||
ScalerProc *scalerProc;
|
ScalerProc *scalerProc;
|
||||||
|
|
||||||
// If possible, use the same scaler for the cursor as for the rest of
|
// Only apply scaling, when the user allows it.
|
||||||
// the game. This only works well with the non-blurring scalers so we
|
if (!_cursorDontScale) {
|
||||||
// actually only use the 1x, 1.5x, 2x and AdvMame scalers.
|
// If possible, use the same scaler for the cursor as for the rest of
|
||||||
|
// the game. This only works well with the non-blurring scalers so we
|
||||||
if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE))
|
// actually only use the 1x, 2x and AdvMame scalers.
|
||||||
scalerProc = _scalerProc;
|
if (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE)
|
||||||
else
|
scalerProc = _scalerProc;
|
||||||
scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1];
|
else
|
||||||
|
scalerProc = scalersMagn[_videoMode.scaleFactor - 1];
|
||||||
|
} else {
|
||||||
|
scalerProc = Normal1x;
|
||||||
|
}
|
||||||
|
|
||||||
scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
|
scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
|
||||||
_mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
|
_mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
|
||||||
_mouseCurState.w, _mouseCurState.h);
|
_mouseCurState.w, _mouseCurState.h);
|
||||||
|
|
||||||
#ifdef USE_SCALERS
|
#ifdef USE_SCALERS
|
||||||
if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1)
|
if (!_cursorDontScale && _videoMode.aspectRatioCorrection)
|
||||||
cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
|
cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
|
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
|
virtual void setMouseCursor(const byte *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 setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
#ifdef USE_OSD
|
#ifdef USE_OSD
|
||||||
|
@ -281,7 +281,7 @@ protected:
|
||||||
#else
|
#else
|
||||||
byte _mouseKeyColor;
|
byte _mouseKeyColor;
|
||||||
#endif
|
#endif
|
||||||
int _cursorTargetScale;
|
bool _cursorDontScale;
|
||||||
bool _cursorPaletteDisabled;
|
bool _cursorPaletteDisabled;
|
||||||
SDL_Surface *_mouseOrigSurface;
|
SDL_Surface *_mouseOrigSurface;
|
||||||
SDL_Surface *_mouseSurface;
|
SDL_Surface *_mouseSurface;
|
||||||
|
|
|
@ -1128,7 +1128,7 @@ void WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x
|
||||||
SDL_UnlockSurface(_screen);
|
SDL_UnlockSurface(_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
|
|
||||||
undrawMouse();
|
undrawMouse();
|
||||||
if (w == 0 || h == 0)
|
if (w == 0 || h == 0)
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
void internDrawMouse();
|
void internDrawMouse();
|
||||||
void undrawMouse();
|
void undrawMouse();
|
||||||
bool showMouse(bool visible);
|
bool showMouse(bool visible);
|
||||||
void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
|
void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); // overloaded by CE backend
|
||||||
void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
||||||
void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
|
void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
|
||||||
Graphics::Surface *lockScreen();
|
Graphics::Surface *lockScreen();
|
||||||
|
|
|
@ -195,8 +195,8 @@ void ModularBackend::warpMouse(int x, int y) {
|
||||||
_graphicsManager->warpMouse(x, y);
|
_graphicsManager->warpMouse(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
_graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format);
|
_graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModularBackend::setCursorPalette(const byte *colors, uint start, uint num) {
|
void ModularBackend::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
|
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
|
virtual void setMouseCursor(const byte *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 setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
|
@ -269,7 +269,7 @@ public:
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
int hotspotY, uint32 keycolor,
|
int hotspotY, uint32 keycolor,
|
||||||
int cursorTargetScale,
|
bool dontScale,
|
||||||
const Graphics::PixelFormat *format);
|
const Graphics::PixelFormat *format);
|
||||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
|
|
|
@ -687,10 +687,10 @@ bool OSystem_Android::showMouse(bool visible) {
|
||||||
|
|
||||||
void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
|
void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
|
||||||
int hotspotX, int hotspotY,
|
int hotspotX, int hotspotY,
|
||||||
uint32 keycolor, int cursorTargetScale,
|
uint32 keycolor, bool dontScale,
|
||||||
const Graphics::PixelFormat *format) {
|
const Graphics::PixelFormat *format) {
|
||||||
ENTER("%p, %u, %u, %d, %d, %u, %d, %p", buf, w, h, hotspotX, hotspotY,
|
ENTER("%p, %u, %u, %d, %d, %u, %d, %p", buf, w, h, hotspotX, hotspotY,
|
||||||
keycolor, cursorTargetScale, format);
|
keycolor, dontScale, format);
|
||||||
|
|
||||||
GLTHREADCHECK;
|
GLTHREADCHECK;
|
||||||
|
|
||||||
|
@ -766,7 +766,8 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
|
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
|
||||||
_mouse_targetscale = cursorTargetScale;
|
// TODO: Adapt to the new "do not scale" cursor logic.
|
||||||
|
_mouse_targetscale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_Android::setCursorPaletteInternal(const byte *colors,
|
void OSystem_Android::setCursorPaletteInternal(const byte *colors,
|
||||||
|
|
|
@ -142,7 +142,7 @@ public:
|
||||||
void warpMouse(int x, int y);
|
void warpMouse(int x, int y);
|
||||||
|
|
||||||
// Set the bitmap that's used when drawing the cursor.
|
// Set the bitmap that's used when drawing the cursor.
|
||||||
void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
|
||||||
|
|
||||||
// Replace the specified range of cursor the palette with new colors.
|
// Replace the specified range of cursor the palette with new colors.
|
||||||
void setCursorPalette(const byte *colors, uint start, uint num);
|
void setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
|
@ -293,7 +293,7 @@ void OSystem_Dreamcast::warpMouse(int x, int y)
|
||||||
|
|
||||||
void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h,
|
void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h,
|
||||||
int hotspot_x, int hotspot_y,
|
int hotspot_x, int hotspot_y,
|
||||||
uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format)
|
uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format)
|
||||||
{
|
{
|
||||||
_ms_cur_w = w;
|
_ms_cur_w = w;
|
||||||
_ms_cur_h = h;
|
_ms_cur_h = h;
|
||||||
|
|
|
@ -580,7 +580,7 @@ bool OSystem_DS::showMouse(bool visible) {
|
||||||
void OSystem_DS::warpMouse(int x, int y) {
|
void OSystem_DS::warpMouse(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format) {
|
void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
if ((w > 0) && (w < 64) && (h > 0) && (h < 64)) {
|
if ((w > 0) && (w < 64) && (h > 0) && (h < 64)) {
|
||||||
memcpy(_cursorImage, buf, w * h);
|
memcpy(_cursorImage, buf, w * h);
|
||||||
_cursorW = w;
|
_cursorW = w;
|
||||||
|
@ -588,7 +588,9 @@ void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, i
|
||||||
_cursorHotX = hotspotX;
|
_cursorHotX = hotspotX;
|
||||||
_cursorHotY = hotspotY;
|
_cursorHotY = hotspotY;
|
||||||
_cursorKey = keycolor;
|
_cursorKey = keycolor;
|
||||||
_cursorScale = targetCursorScale;
|
// TODO: The old target scales was saved, but never used. Should the
|
||||||
|
// new "do not scale" logic be implemented?
|
||||||
|
//_cursorScale = targetCursorScale;
|
||||||
refreshCursor();
|
refreshCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public:
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
|
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format);
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
|
||||||
|
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
virtual uint32 getMillis();
|
virtual uint32 getMillis();
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
|
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
|
||||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
|
|
@ -398,8 +398,8 @@ void OSystem_IPHONE::dirtyFullOverlayScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
//printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, (const void *)format);
|
//printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, dontScale, (const void *)format);
|
||||||
|
|
||||||
const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
|
const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -182,7 +182,7 @@ public:
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
|
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
virtual void setMouseCursor(const byte *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 setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
|
|
@ -773,7 +773,7 @@ void OSystem_N64::warpMouse(int x, int y) {
|
||||||
_dirtyOffscreen = true;
|
_dirtyOffscreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
if (!w || !h) return;
|
if (!w || !h) return;
|
||||||
|
|
||||||
_mouseHotspotX = hotspotX;
|
_mouseHotspotX = hotspotX;
|
||||||
|
|
|
@ -618,7 +618,7 @@ void OSystem_PS2::warpMouse(int x, int y) {
|
||||||
_screen->setMouseXy(x, y);
|
_screen->setMouseXy(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
_screen->setMouseOverlay(buf, w, h, hotspot_x, hotspot_y, keycolor);
|
_screen->setMouseOverlay(buf, w, h, hotspot_x, hotspot_y, keycolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
virtual bool showMouse(bool visible);
|
virtual bool showMouse(bool visible);
|
||||||
|
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = 0);
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = 0);
|
||||||
|
|
||||||
virtual uint32 getMillis();
|
virtual uint32 getMillis();
|
||||||
virtual void delayMillis(uint msecs);
|
virtual void delayMillis(uint msecs);
|
||||||
|
|
|
@ -303,7 +303,7 @@ void OSystem_PSP::warpMouse(int x, int y) {
|
||||||
_cursor.setXY(x, y);
|
_cursor.setXY(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
|
void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
DEBUG_ENTER_FUNC();
|
DEBUG_ENTER_FUNC();
|
||||||
_displayManager.waitUntilRenderFinished();
|
_displayManager.waitUntilRenderFinished();
|
||||||
_pendingUpdate = false;
|
_pendingUpdate = false;
|
||||||
|
@ -314,7 +314,9 @@ void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
}
|
}
|
||||||
|
|
||||||
_cursor.setKeyColor(keycolor);
|
_cursor.setKeyColor(keycolor);
|
||||||
_cursor.setCursorTargetScale(cursorTargetScale);
|
// TODO: The old target scale was saved but never used. Should the new
|
||||||
|
// "do not scale" logic be implemented?
|
||||||
|
//_cursor.setCursorTargetScale(cursorTargetScale);
|
||||||
_cursor.setSizeAndScummvmPixelFormat(w, h, format);
|
_cursor.setSizeAndScummvmPixelFormat(w, h, format);
|
||||||
_cursor.setHotspot(hotspotX, hotspotY);
|
_cursor.setHotspot(hotspotX, hotspotY);
|
||||||
_cursor.clearKeyColor();
|
_cursor.clearKeyColor();
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
// Mouse related
|
// Mouse related
|
||||||
bool showMouse(bool visible);
|
bool showMouse(bool visible);
|
||||||
void warpMouse(int x, int y);
|
void warpMouse(int x, int y);
|
||||||
void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
|
||||||
|
|
||||||
// Events and input
|
// Events and input
|
||||||
bool pollEvent(Common::Event &event);
|
bool pollEvent(Common::Event &event);
|
||||||
|
|
|
@ -189,7 +189,7 @@ public:
|
||||||
virtual void warpMouse(int x, int y);
|
virtual void warpMouse(int x, int y);
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
int hotspotY, uint32 keycolor,
|
int hotspotY, uint32 keycolor,
|
||||||
int cursorTargetScale,
|
bool dontScale,
|
||||||
const Graphics::PixelFormat *format);
|
const Graphics::PixelFormat *format);
|
||||||
|
|
||||||
virtual bool pollEvent(Common::Event &event);
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
|
|
@ -644,7 +644,7 @@ void OSystem_Wii::warpMouse(int x, int y) {
|
||||||
|
|
||||||
void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
int hotspotY, uint32 keycolor,
|
int hotspotY, uint32 keycolor,
|
||||||
int cursorTargetScale,
|
bool dontScale,
|
||||||
const Graphics::PixelFormat *format) {
|
const Graphics::PixelFormat *format) {
|
||||||
gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3;
|
gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3;
|
||||||
uint tw, th;
|
uint tw, th;
|
||||||
|
@ -742,7 +742,8 @@ void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
|
|
||||||
_mouseHotspotX = hotspotX;
|
_mouseHotspotX = hotspotX;
|
||||||
_mouseHotspotY = hotspotY;
|
_mouseHotspotY = hotspotY;
|
||||||
_cursorScale = cursorTargetScale;
|
// TODO: Adapt to new dontScale logic!
|
||||||
|
_cursorScale = 1;
|
||||||
|
|
||||||
if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor))
|
if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor))
|
||||||
_cursorPaletteDirty = true;
|
_cursorPaletteDirty = true;
|
||||||
|
|
|
@ -883,10 +883,11 @@ public:
|
||||||
* @param keycolor transparency color value. This should not exceed the maximum color value of the specified format.
|
* @param keycolor transparency color value. This should not exceed the maximum color value of the specified format.
|
||||||
* In case it does the behavior is undefined. The backend might just error out or simply ignore the
|
* In case it does the behavior is undefined. The backend might just error out or simply ignore the
|
||||||
* value. (The SDL backend will just assert to prevent abuse of this).
|
* value. (The SDL backend will just assert to prevent abuse of this).
|
||||||
* @param cursorTargetScale scale factor which cursor is designed for
|
* @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
|
||||||
|
* would be too small to notice otherwise, these are allowed to scale the cursor anyway.
|
||||||
* @param format pointer to the pixel format which cursor graphic uses (0 means CLUT8)
|
* @param format pointer to the pixel format which cursor graphic uses (0 means CLUT8)
|
||||||
*/
|
*/
|
||||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
|
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the specified range of cursor the palette with new colors.
|
* Replace the specified range of cursor the palette with new colors.
|
||||||
|
|
|
@ -123,7 +123,7 @@ void Draw_v1::animateCursor(int16 cursor) {
|
||||||
(cursorIndex + 1) * _cursorWidth - 1,
|
(cursorIndex + 1) * _cursorWidth - 1,
|
||||||
_cursorHeight - 1, 0, 0);
|
_cursorHeight - 1, 0, 0);
|
||||||
CursorMan.replaceCursor(_scummvmCursor->getData(),
|
CursorMan.replaceCursor(_scummvmCursor->getData(),
|
||||||
_cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat());
|
_cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, false, &_vm->getPixelFormat());
|
||||||
|
|
||||||
if (_frontSurface != _backSurface) {
|
if (_frontSurface != _backSurface) {
|
||||||
_showCursor = 3;
|
_showCursor = 3;
|
||||||
|
|
|
@ -161,7 +161,7 @@ void Draw_v2::animateCursor(int16 cursor) {
|
||||||
keyColor = _cursorKeyColors[cursorIndex];
|
keyColor = _cursorKeyColors[cursorIndex];
|
||||||
|
|
||||||
CursorMan.replaceCursor(_scummvmCursor->getData(),
|
CursorMan.replaceCursor(_scummvmCursor->getData(),
|
||||||
_cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat());
|
_cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, false, &_vm->getPixelFormat());
|
||||||
|
|
||||||
if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) {
|
if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) {
|
||||||
CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
|
CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
|
||||||
|
|
|
@ -387,7 +387,7 @@ void Cursor_v2::enable() {
|
||||||
|
|
||||||
void Cursor_v2::showFrame(uint16 frame) {
|
void Cursor_v2::showFrame(uint16 frame) {
|
||||||
int offset = _width * _height * frame * 2;
|
int offset = _width * _height * frame * 2;
|
||||||
CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, 1, &_format);
|
CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, false, &_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ void Cursor::setStyle(CursorStyle style) {
|
||||||
Graphics::PixelFormat pf = g_system->getScreenFormat();
|
Graphics::PixelFormat pf = g_system->getScreenFormat();
|
||||||
CursorMan.replaceCursor((const byte *)getCursorImage(style),
|
CursorMan.replaceCursor((const byte *)getCursorImage(style),
|
||||||
32, 32, _cursors[style].hotspotX, _cursors[style].hotspotY,
|
32, 32, _cursors[style].hotspotX, _cursors[style].hotspotY,
|
||||||
0, 1, &pf);
|
0, false, &pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16 *Cursor::getCursorImage(CursorStyle style) const {
|
const uint16 *Cursor::getCursorImage(CursorStyle style) const {
|
||||||
|
|
|
@ -125,7 +125,7 @@ void MystCursorManager::setCursor(uint16 id) {
|
||||||
CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
|
CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
|
||||||
} else {
|
} else {
|
||||||
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
|
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
|
||||||
CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), 1, &pixelFormat);
|
CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm->_needsUpdate = true;
|
_vm->_needsUpdate = true;
|
||||||
|
|
|
@ -121,13 +121,13 @@ void ScummEngine::updateCursor() {
|
||||||
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
||||||
_cursor.hotspotX, _cursor.hotspotY,
|
_cursor.hotspotX, _cursor.hotspotY,
|
||||||
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
||||||
(_game.heversion == 70 ? 2 : 1),
|
(_game.heversion == 70 ? true : false),
|
||||||
&format);
|
&format);
|
||||||
#else
|
#else
|
||||||
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
|
||||||
_cursor.hotspotX, _cursor.hotspotY,
|
_cursor.hotspotX, _cursor.hotspotY,
|
||||||
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
|
||||||
(_game.heversion == 70 ? 2 : 1));
|
(_game.heversion == 70 ? true : false));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,14 +55,14 @@ bool CursorManager::showMouse(bool visible) {
|
||||||
return g_system->showMouse(visible);
|
return g_system->showMouse(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
|
void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||||
|
|
||||||
cur->_visible = isVisible();
|
cur->_visible = isVisible();
|
||||||
_cursorStack.push(cur);
|
_cursorStack.push(cur);
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ void CursorManager::popCursor() {
|
||||||
|
|
||||||
if (!_cursorStack.empty()) {
|
if (!_cursorStack.empty()) {
|
||||||
cur = _cursorStack.top();
|
cur = _cursorStack.top();
|
||||||
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale, &cur->_format);
|
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_system->showMouse(isVisible());
|
g_system->showMouse(isVisible());
|
||||||
|
@ -98,10 +98,10 @@ void CursorManager::popAllCursors() {
|
||||||
g_system->showMouse(isVisible());
|
g_system->showMouse(isVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
|
void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
|
|
||||||
if (_cursorStack.empty()) {
|
if (_cursorStack.empty()) {
|
||||||
pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
cur->_hotspotX = hotspotX;
|
cur->_hotspotX = hotspotX;
|
||||||
cur->_hotspotY = hotspotY;
|
cur->_hotspotY = hotspotY;
|
||||||
cur->_keycolor = keycolor;
|
cur->_keycolor = keycolor;
|
||||||
cur->_targetScale = targetScale;
|
cur->_dontScale = dontScale;
|
||||||
#ifdef USE_RGB_COLOR
|
#ifdef USE_RGB_COLOR
|
||||||
if (format)
|
if (format)
|
||||||
cur->_format = *format;
|
cur->_format = *format;
|
||||||
|
@ -139,7 +139,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
|
||||||
cur->_format = Graphics::PixelFormat::createFormatCLUT8();
|
cur->_format = Graphics::PixelFormat::createFormatCLUT8();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
|
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CursorManager::supportsCursorPalettes() {
|
bool CursorManager::supportsCursorPalettes() {
|
||||||
|
@ -225,7 +225,7 @@ void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint nu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
|
CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||||
#ifdef USE_RGB_COLOR
|
#ifdef USE_RGB_COLOR
|
||||||
if (!format)
|
if (!format)
|
||||||
_format = Graphics::PixelFormat::createFormatCLUT8();
|
_format = Graphics::PixelFormat::createFormatCLUT8();
|
||||||
|
@ -245,7 +245,7 @@ CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, in
|
||||||
_height = h;
|
_height = h;
|
||||||
_hotspotX = hotspotX;
|
_hotspotX = hotspotX;
|
||||||
_hotspotY = hotspotY;
|
_hotspotY = hotspotY;
|
||||||
_targetScale = targetScale;
|
_dontScale = dontScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorManager::Cursor::~Cursor() {
|
CursorManager::Cursor::~Cursor() {
|
||||||
|
|
|
@ -63,14 +63,15 @@ public:
|
||||||
* @param hotspotY the hotspot Y coordinate
|
* @param hotspotY the hotspot Y coordinate
|
||||||
* @param keycolor the color value for the transparent color. This may not exceed
|
* @param keycolor the color value for the transparent color. This may not exceed
|
||||||
* the maximum color value as defined by format.
|
* the maximum color value as defined by format.
|
||||||
* @param targetScale the scale for which the cursor is designed
|
* @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
|
||||||
|
* would be too small to notice otherwise, these are allowed to scale the cursor anyway.
|
||||||
* @param format a pointer to the pixel format which the cursor graphic uses,
|
* @param format a pointer to the pixel format which the cursor graphic uses,
|
||||||
* CLUT8 will be used if this is NULL or not specified.
|
* CLUT8 will be used if this is NULL or not specified.
|
||||||
* @note It is ok for the buffer to be a NULL pointer. It is sometimes
|
* @note It is ok for the buffer to be a NULL pointer. It is sometimes
|
||||||
* useful to push a "dummy" cursor and modify it later. The
|
* useful to push a "dummy" cursor and modify it later. The
|
||||||
* cursor will be added to the stack, but not to the backend.
|
* cursor will be added to the stack, but not to the backend.
|
||||||
*/
|
*/
|
||||||
void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
|
void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop a cursor from the stack, and restore the previous one to the
|
* Pop a cursor from the stack, and restore the previous one to the
|
||||||
|
@ -90,11 +91,12 @@ public:
|
||||||
* @param hotspotY the hotspot Y coordinate
|
* @param hotspotY the hotspot Y coordinate
|
||||||
* @param keycolor the color value for the transparent color. This may not exceed
|
* @param keycolor the color value for the transparent color. This may not exceed
|
||||||
* the maximum color value as defined by format.
|
* the maximum color value as defined by format.
|
||||||
* @param targetScale the scale for which the cursor is designed
|
* @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
|
||||||
|
* would be too small to notice otherwise, these are allowed to scale the cursor anyway.
|
||||||
* @param format a pointer to the pixel format which the cursor graphic uses,
|
* @param format a pointer to the pixel format which the cursor graphic uses,
|
||||||
* CLUT8 will be used if this is NULL or not specified.
|
* CLUT8 will be used if this is NULL or not specified.
|
||||||
*/
|
*/
|
||||||
void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
|
void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop all of the cursors and cursor palettes from their respective stacks.
|
* Pop all of the cursors and cursor palettes from their respective stacks.
|
||||||
|
@ -175,11 +177,11 @@ private:
|
||||||
int _hotspotY;
|
int _hotspotY;
|
||||||
uint32 _keycolor;
|
uint32 _keycolor;
|
||||||
Graphics::PixelFormat _format;
|
Graphics::PixelFormat _format;
|
||||||
int _targetScale;
|
bool _dontScale;
|
||||||
|
|
||||||
uint _size;
|
uint _size;
|
||||||
|
|
||||||
Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
|
Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
|
||||||
~Cursor();
|
~Cursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -454,7 +454,7 @@ void ThemeEngine::refresh() {
|
||||||
|
|
||||||
if (_useCursor) {
|
if (_useCursor) {
|
||||||
CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
|
CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
|
||||||
CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
|
CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ void ThemeEngine::enable() {
|
||||||
|
|
||||||
if (_useCursor) {
|
if (_useCursor) {
|
||||||
CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
|
CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
|
||||||
CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
|
CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
|
||||||
CursorMan.showMouse(true);
|
CursorMan.showMouse(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,7 +1287,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
|
||||||
_vectorRenderer->setSurface(&_screen);
|
_vectorRenderer->setSurface(&_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) {
|
bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY) {
|
||||||
if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
|
if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1305,7 +1305,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
|
||||||
// Set up the cursor parameters
|
// Set up the cursor parameters
|
||||||
_cursorHotspotX = hotspotX;
|
_cursorHotspotX = hotspotX;
|
||||||
_cursorHotspotY = hotspotY;
|
_cursorHotspotY = hotspotY;
|
||||||
_cursorTargetScale = scale;
|
|
||||||
|
|
||||||
_cursorWidth = cursor->w;
|
_cursorWidth = cursor->w;
|
||||||
_cursorHeight = cursor->h;
|
_cursorHeight = cursor->h;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "graphics/pixelformat.h"
|
#include "graphics/pixelformat.h"
|
||||||
|
|
||||||
|
|
||||||
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.12"
|
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.13"
|
||||||
|
|
||||||
class OSystem;
|
class OSystem;
|
||||||
|
|
||||||
|
@ -495,9 +495,8 @@ public:
|
||||||
* @param filename File name of the bitmap to load.
|
* @param filename File name of the bitmap to load.
|
||||||
* @param hotspotX X Coordinate of the bitmap which does the cursor click.
|
* @param hotspotX X Coordinate of the bitmap which does the cursor click.
|
||||||
* @param hotspotY Y Coordinate of the bitmap which does the cursor click.
|
* @param hotspotY Y Coordinate of the bitmap which does the cursor click.
|
||||||
* @param scale Scale at which the bitmap is supposed to be used.
|
|
||||||
*/
|
*/
|
||||||
bool createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale);
|
bool createCursor(const Common::String &filename, int hotspotX, int hotspotY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for restoring data from the Back Buffer to the screen.
|
* Wrapper for restoring data from the Back Buffer to the screen.
|
||||||
|
@ -669,7 +668,6 @@ protected:
|
||||||
|
|
||||||
bool _useCursor;
|
bool _useCursor;
|
||||||
int _cursorHotspotX, _cursorHotspotY;
|
int _cursorHotspotX, _cursorHotspotY;
|
||||||
int _cursorTargetScale;
|
|
||||||
enum {
|
enum {
|
||||||
MAX_CURS_COLORS = 255
|
MAX_CURS_COLORS = 255
|
||||||
};
|
};
|
||||||
|
|
|
@ -218,15 +218,12 @@ bool ThemeParser::parserCallback_cursor(ParserNode *node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spotx, spoty, scale;
|
int spotx, spoty;
|
||||||
|
|
||||||
if (!parseIntegerKey(node->values["hotspot"], 2, &spotx, &spoty))
|
if (!parseIntegerKey(node->values["hotspot"], 2, &spotx, &spoty))
|
||||||
return parserError("Error parsing cursor Hot Spot coordinates.");
|
return parserError("Error parsing cursor Hot Spot coordinates.");
|
||||||
|
|
||||||
if (!parseIntegerKey(node->values["scale"], 1, &scale))
|
if (!_theme->createCursor(node->values["file"], spotx, spoty))
|
||||||
return parserError("Error parsing cursor scale.");
|
|
||||||
|
|
||||||
if (!_theme->createCursor(node->values["file"], spotx, spoty, scale))
|
|
||||||
return parserError("Error creating Bitmap Cursor.");
|
return parserError("Error creating Bitmap Cursor.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -85,7 +85,6 @@ protected:
|
||||||
XML_KEY(cursor)
|
XML_KEY(cursor)
|
||||||
XML_PROP(file, true)
|
XML_PROP(file, true)
|
||||||
XML_PROP(hotspot, true)
|
XML_PROP(hotspot, true)
|
||||||
XML_PROP(scale, true)
|
|
||||||
XML_PROP(resolution, false)
|
XML_PROP(resolution, false)
|
||||||
KEY_END()
|
KEY_END()
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -1 +1 @@
|
||||||
[SCUMMVM_STX0.8.12:ScummVM Classic Theme:No Author]
|
[SCUMMVM_STX0.8.13:ScummVM Classic Theme:No Author]
|
||||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
[SCUMMVM_STX0.8.12:ScummVM Modern Theme:No Author]
|
[SCUMMVM_STX0.8.13:ScummVM Modern Theme:No Author]
|
||||||
|
|
|
@ -187,8 +187,8 @@
|
||||||
|
|
||||||
<!-- <defaults fill = 'gradient' fg_color = 'white'/> -->
|
<!-- <defaults fill = 'gradient' fg_color = 'white'/> -->
|
||||||
|
|
||||||
<cursor file = 'cursor.bmp' hotspot = '0, 0' scale = '3'/>
|
<cursor file = 'cursor.bmp' hotspot = '0, 0'/>
|
||||||
<cursor resolution = 'y<400' file = 'cursor_small.bmp' hotspot = '0, 0' scale = '3'/>
|
<cursor resolution = 'y<400' file = 'cursor_small.bmp' hotspot = '0, 0'/>
|
||||||
|
|
||||||
<!-- Selection (text or list items) -->
|
<!-- Selection (text or list items) -->
|
||||||
<drawdata id = 'text_selection' cache = 'false'>
|
<drawdata id = 'text_selection' cache = 'false'>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue