Fixed cursor code to keep track of cursor formats so that ThemeEngine and/or GuiManager cursors will render properly over the game (on spacebar hit, for instance)

svn-id: r41491
This commit is contained in:
Jody Northup 2009-06-13 10:24:52 +00:00
parent 2ee51a8fa1
commit 350dc4290f
9 changed files with 136 additions and 12 deletions

View file

@ -1249,10 +1249,18 @@ void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) {
}
_cursorPaletteDisabled = false;
blitCursor();
#ifdef ENABLE_16BIT
}
void OSystem_SDL::setCursorFormat(Graphics::PixelFormat format) {
assert(format.bytesPerPixel);
_cursorFormat = format;
#endif
// blitCursor();
}
void OSystem_SDL::setShakePos(int shake_pos) {
assert (_transactionMode == kTransactionNone);
@ -1459,7 +1467,7 @@ void OSystem_SDL::warpMouse(int x, int y) {
#ifdef ENABLE_16BIT
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale) {
keycolor &= (1 << (_screenFormat.bytesPerPixel << 3)) - 1;
keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
#else
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
#endif
@ -1498,8 +1506,8 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x,
free(_mouseData);
#ifdef ENABLE_16BIT
_mouseData = (byte *)malloc(w * h * _screenFormat.bytesPerPixel);
memcpy(_mouseData, buf, w * h * _screenFormat.bytesPerPixel);
_mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
#else
_mouseData = (byte *)malloc(w * h);
memcpy(_mouseData, buf, w * h);
@ -1513,7 +1521,7 @@ void OSystem_SDL::blitCursor() {
const byte *srcPtr = _mouseData;
#ifdef ENABLE_16BIT
uint32 color;
uint32 colormask = (1 << (_screenFormat.bytesPerPixel << 3)) - 1;
uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
#else
byte color;
#endif
@ -1551,16 +1559,16 @@ void OSystem_SDL::blitCursor() {
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
#ifdef ENABLE_16BIT
if (_screenFormat.bytesPerPixel > 1) {
if (_cursorFormat.bytesPerPixel > 1) {
color = (*(uint32 *) srcPtr) & colormask;
if (color != _mouseKeyColor) { // transparent, don't draw
uint8 r,g,b;
_screenFormat.colorToRGB(color,r,g,b);
_cursorFormat.colorToRGB(color,r,g,b);
*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
r, g, b);
}
dstPtr += 2;
srcPtr += _screenFormat.bytesPerPixel;
srcPtr += _cursorFormat.bytesPerPixel;
} else {
#endif
color = *srcPtr;

View file

@ -130,6 +130,7 @@ public:
// Set the bitmap that's used when drawing the cursor.
#ifdef ENABLE_16BIT
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME)
virtual void setCursorFormat(Graphics::PixelFormat format);
#else
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME)
#endif
@ -250,6 +251,7 @@ protected:
SDL_Surface *_screen;
#ifdef ENABLE_16BIT
Graphics::PixelFormat _screenFormat;
Graphics::PixelFormat _cursorFormat;
#endif
// temporary screen (for scalers)

View file

@ -739,6 +739,7 @@ public:
*/
#ifdef ENABLE_16BIT
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int cursorTargetScale = 1) = 0;
virtual void setCursorFormat(Graphics::PixelFormat format) = 0;
#else
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0;
#endif

View file

@ -112,6 +112,9 @@ void ScummEngine_v6::setCursorTransparency(int a) {
void ScummEngine::updateCursor() {
int transColor = (_game.heversion >= 80) ? 5 : 255;
#ifdef ENABLE_16BIT
CursorMan.replaceCursorFormat(_system->getScreenFormat());
#endif
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
_cursor.hotspotX, _cursor.hotspotY,
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),

View file

@ -101,6 +101,13 @@ void CursorManager::popAllCursors() {
}
}
#ifdef ENABLE_16BIT
while (!_cursorFormatStack.empty()) {
PixelFormat *form = _cursorFormatStack.pop();
delete form;
}
#endif
g_system->showMouse(isVisible());
}
@ -118,8 +125,8 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
Cursor *cur = _cursorStack.top();
#ifdef ENABLE_16BIT
uint size;
{ //limit the lifespan of the format variable to minimize memory impact
uint size;
{ //limit the lifespan of the format variable to minimize memory impact
Graphics::PixelFormat f = g_system->getScreenFormat();
size = w * h * (f.bytesPerPixel);
}
@ -225,4 +232,48 @@ void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint nu
}
}
#ifdef ENABLE_16BIT
void CursorManager::pushCursorFormat(PixelFormat format) {
// if (!g_system->hasFeature(OSystem::kFeatureCursorHasPalette))
// return;
PixelFormat *form = new PixelFormat(format);
_cursorFormatStack.push(form);
g_system->setCursorFormat(format);
}
void CursorManager::popCursorFormat() {
if (_cursorFormatStack.empty())
return;
PixelFormat *form = _cursorFormatStack.pop();
delete form;
if (_cursorFormatStack.empty()) {
g_system->setCursorFormat(g_system->getScreenFormat());
return;
}
form = _cursorFormatStack.top();
disableCursorPalette(form->bytesPerPixel != 1);
g_system->setCursorFormat(*form);
}
void CursorManager::replaceCursorFormat(PixelFormat format) {
// if (!g_system->hasFeature(OSystem::kFeatureCursorHasPalette))
// return;
if (_cursorFormatStack.empty()) {
pushCursorFormat(format);
return;
}
PixelFormat *form = _cursorFormatStack.top();
g_system->setCursorFormat(*form);
}
#endif
} // End of namespace Graphics

View file

@ -142,6 +142,31 @@ public:
*/
void replaceCursorPalette(const byte *colors, uint start, uint num);
#ifdef ENABLE_16BIT
/**
* Push a new cursor pixel format onto the stack, and set it in the backend.
*
* @param format the new format data, in a Graphics::PixelFormat
*/
void pushCursorFormat(PixelFormat format);
/**
* Pop a cursor pixel format from the stack, and restore the previous one to
* the backend. If there is no previous format, the screen format is
* used instead.
*/
void popCursorFormat();
/**
* Replace the current cursor pixel format on the stack. If the stack is
* empty, the format is pushed instead. It's a slightly more optimized
* way of popping the old format before pushing the new one.
*
* @param format the new format data, in a Graphics::PixelFormat
*/
void replaceCursorFormat(PixelFormat format);
#endif
private:
friend class Common::Singleton<SingletonBaseType>;
CursorManager();
@ -216,9 +241,11 @@ private:
delete[] _data;
}
};
Common::Stack<Cursor *> _cursorStack;
Common::Stack<Palette *> _cursorPaletteStack;
#ifdef ENABLE_16BIT
Common::Stack<Graphics::PixelFormat *> _cursorFormatStack;
#endif
};
} // End of namespace Graphics

View file

@ -135,6 +135,9 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx)
delete _theme;
if (_useStdCursor) {
#ifdef ENABLE_16BIT
CursorMan.popCursorFormat();
#endif
CursorMan.popCursorPalette();
CursorMan.popCursor();
}
@ -382,6 +385,9 @@ void GuiManager::saveState() {
void GuiManager::restoreState() {
if (_useStdCursor) {
#ifdef ENABLE_16BIT
CursorMan.popCursorFormat();
#endif
CursorMan.popCursor();
CursorMan.popCursorPalette();
}
@ -424,6 +430,14 @@ void GuiManager::setupCursor() {
87, 87, 87, 0
};
#ifdef ENABLE_16BIT
Graphics::PixelFormat format;
format.bytesPerPixel = 1;
format.rLoss = format.gLoss = format.bLoss = format.aLoss = 8;
format.rShift = format.gShift = format.bShift = format.aShift = 0;
CursorMan.pushCursorFormat(format);
#endif
CursorMan.pushCursorPalette(palette, 0, 4);
CursorMan.pushCursor(NULL, 0, 0, 0, 0);
CursorMan.showMouse(true);

View file

@ -434,6 +434,9 @@ void ThemeEngine::refresh() {
_system->showOverlay();
if (_useCursor) {
#ifdef ENABLE_16BIT
CursorMan.replaceCursorFormat(_cursorFormat);
#endif
CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
}
@ -445,6 +448,9 @@ void ThemeEngine::enable() {
return;
if (_useCursor) {
#ifdef ENABLE_16BIT
CursorMan.pushCursorFormat(_system->getScreenFormat());
#endif
CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
CursorMan.showMouse(true);
@ -462,6 +468,9 @@ void ThemeEngine::disable() {
_system->hideOverlay();
if (_useCursor) {
#ifdef ENABLE_16BIT
CursorMan.popCursorFormat();
#endif
CursorMan.popCursorPalette();
CursorMan.popCursor();
}
@ -1165,6 +1174,12 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
if (!cursor)
return false;
#ifdef ENABLE_16BIT
_cursorFormat.bytesPerPixel = 1;
_cursorFormat.rLoss = _cursorFormat.gLoss = _cursorFormat.bLoss = _cursorFormat.aLoss = 8;
_cursorFormat.rShift = _cursorFormat.gShift = _cursorFormat.bShift = _cursorFormat.aShift = 0;
#endif
// Set up the cursor parameters
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;

View file

@ -579,6 +579,9 @@ protected:
ImagesMap _bitmaps;
Graphics::PixelFormat _overlayFormat;
#ifdef ENABLE_16BIT
Graphics::PixelFormat _cursorFormat;
#endif
/** List of all the dirty screens that must be blitted to the overlay. */
Common::List<Common::Rect> _dirtyScreen;