[Scummvm-git-logs] scummvm master -> 8363aeacef38a935ea7f84381dd20c2c2750d4c5
sev-
noreply at scummvm.org
Sun Apr 9 11:12:12 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
dd1232325d GRAPHICS: Add support for cursor as Surface
38ffb065f5 MADE: Use new CursorMan with cursor surface
8e1aa562a3 ASYLUM: Use new CursorMan with cursor surface
8363aeacef ASYLUM: Use standard surface handling
Commit: dd1232325d9b310a85244f78ca5d12c063cf047f
https://github.com/scummvm/scummvm/commit/dd1232325d9b310a85244f78ca5d12c063cf047f
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-09T13:12:06+02:00
Commit Message:
GRAPHICS: Add support for cursor as Surface
This helps engines which pass Surface buffers to replaceCursor() and
pushCursor() while the surface is not guaranteed to have width == pitch.
Changed paths:
graphics/cursorman.cpp
graphics/cursorman.h
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 3853132595c..6cd3425fe2b 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -21,6 +21,7 @@
#include "graphics/cursorman.h"
+#include "common/rect.h"
#include "common/system.h"
#include "common/stack.h"
@@ -59,15 +60,31 @@ bool CursorManager::showMouse(bool visible) {
}
void CursorManager::pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
+ PixelFormat pixelFormat;
+#ifdef USE_RGB_COLOR
+ if (format)
+ pixelFormat = *format;
+ else
+#endif
+ pixelFormat = PixelFormat::createFormatCLUT8();
+
+ Surface surf;
+ // we wont touch 'buf' ...
+ surf.init(w, h, w, const_cast<void *>(buf), pixelFormat);
+
+ pushCursor(surf, hotspotX, hotspotY, keycolor, dontScale, mask);
+}
+
+void CursorManager::pushCursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const byte *mask) {
if (!g_system->hasFeature(OSystem::kFeatureCursorMask))
mask = nullptr;
- Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
+ Cursor *cur = new Cursor(surf, hotspotX, hotspotY, keycolor, dontScale, mask);
cur->_visible = isVisible();
_cursorStack.push(cur);
- g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
+ g_system->setMouseCursor(cur->_surf.getPixels(), cur->_surf.w, cur->_surf.h, hotspotX, hotspotY, keycolor, dontScale, &cur->_surf.format, mask);
}
void CursorManager::popCursor() {
@@ -79,7 +96,7 @@ 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, cur->_mask);
+ g_system->setMouseCursor(cur->_surf.getPixels(), cur->_surf.w, cur->_surf.h, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_surf.format, cur->_mask);
} else {
g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
}
@@ -106,57 +123,65 @@ void CursorManager::popAllCursors() {
}
void CursorManager::replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
+ PixelFormat pixelFormat;
+#ifdef USE_RGB_COLOR
+ if (format)
+ pixelFormat = *format;
+ else
+#endif
+ pixelFormat = PixelFormat::createFormatCLUT8();
+
+ Surface surf;
+ // we wont touch 'buf' ...
+ surf.init(w, h, w, const_cast<void *>(buf), pixelFormat);
+
+ replaceCursor(surf, hotspotX, hotspotY, keycolor, dontScale, mask);
+}
+
+void CursorManager::replaceCursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const byte *mask) {
if (!g_system->hasFeature(OSystem::kFeatureCursorMask))
mask = nullptr;
if (_cursorStack.empty()) {
- pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
+ pushCursor(surf, hotspotX, hotspotY, keycolor, dontScale, mask);
return;
}
Cursor *cur = _cursorStack.top();
-#ifdef USE_RGB_COLOR
- uint size;
- if (!format)
- size = w * h;
- else
- size = w * h * format->bytesPerPixel;
-#else
- uint size = w * h;
-#endif
+ const uint size = surf.w * surf.h * surf.format.bytesPerPixel;
if (cur->_size < size) {
- delete[] cur->_data;
- cur->_data = new byte[size];
+ // Don't use Surface::create() here because that doesn't guarantee
+ // linearity of the surface buffer (i.e. pitch must be the same as
+ // width).
+ delete[] (byte *)cur->_surf.getPixels();
+ cur->_surf.setPixels(new byte[size]);
cur->_size = size;
}
- if (buf && cur->_data)
- memcpy(cur->_data, buf, size);
+ cur->_surf.pitch = surf.w;
+ cur->_surf.w = surf.w;
+ cur->_surf.h = surf.h;
+ cur->_surf.format = surf.format;
+
+ if (surf.getPixels() && cur->_surf.getPixels())
+ cur->_surf.copyRectToSurface(surf, 0, 0, Common::Rect(surf.w, surf.h));
delete[] cur->_mask;
cur->_mask = nullptr;
if (mask) {
- cur->_mask = new byte[w * h];
- memcpy(cur->_mask, mask, w * h);
+ cur->_mask = new byte[surf.w * surf.h];
+ memcpy(cur->_mask, mask, surf.w * surf.h);
}
- cur->_width = w;
- cur->_height = h;
cur->_hotspotX = hotspotX;
cur->_hotspotY = hotspotY;
cur->_keycolor = keycolor;
cur->_dontScale = dontScale;
-#ifdef USE_RGB_COLOR
- if (format)
- cur->_format = *format;
- else
- cur->_format = Graphics::PixelFormat::createFormatCLUT8();
-#endif
- g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format, mask);
+ g_system->setMouseCursor(cur->_surf.getPixels(), surf.w, surf.h, hotspotX, hotspotY, keycolor, dontScale, &surf.format, mask);
}
void CursorManager::replaceCursor(const Graphics::Cursor *cursor) {
@@ -254,31 +279,27 @@ void CursorManager::lock(bool locked) {
_locked = locked;
}
-CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
+CursorManager::Cursor::Cursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const byte *mask) {
#ifdef USE_RGB_COLOR
- if (!format)
- _format = Graphics::PixelFormat::createFormatCLUT8();
- else
- _format = *format;
- _size = w * h * _format.bytesPerPixel;
- const uint32 keycolor_mask = (((uint32) -1) >> (sizeof(uint32) * 8 - _format.bytesPerPixel * 8));
+ const uint32 keycolor_mask = (((uint32) -1) >> (sizeof(uint32) * 8 - surf.format.bytesPerPixel * 8));
_keycolor = keycolor & keycolor_mask;
#else
- _format = Graphics::PixelFormat::createFormatCLUT8();
- _size = w * h;
_keycolor = keycolor & 0xFF;
#endif
- _data = new byte[_size];
- if (data && _data)
- memcpy(_data, data, _size);
+ _size = surf.w * surf.h * surf.format.bytesPerPixel;
+
+ // make sure that the width == pitch
+ _surf.init(surf.w, surf.h, surf.w, new byte[_size], surf.format);
+ if (surf.getPixels() && _surf.getPixels())
+ _surf.copyRectToSurface(surf, 0, 0, Common::Rect(surf.w, surf.h));
+
if (mask) {
- _mask = new byte[w * h];
+ _mask = new byte[surf.w * surf.h];
if (_mask)
- memcpy(_mask, mask, w * h);
+ memcpy(_mask, mask, surf.w * surf.h);
} else
_mask = nullptr;
- _width = w;
- _height = h;
+
_hotspotX = hotspotX;
_hotspotY = hotspotY;
_dontScale = dontScale;
@@ -286,7 +307,7 @@ CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, in
}
CursorManager::Cursor::~Cursor() {
- delete[] _data;
+ delete[] (byte *)_surf.getPixels();
delete[] _mask;
}
diff --git a/graphics/cursorman.h b/graphics/cursorman.h
index 876c46ac610..14d2545cb88 100644
--- a/graphics/cursorman.h
+++ b/graphics/cursorman.h
@@ -26,7 +26,7 @@
#include "common/stack.h"
#include "common/singleton.h"
#include "graphics/cursor.h"
-#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
namespace Graphics {
@@ -85,7 +85,29 @@ public:
* useful to push a "dummy" cursor and modify it later. The
* cursor will be added to the stack, but not to the backend.
*/
- void pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = NULL);
+ void pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = nullptr);
+
+ /**
+ * Push a new cursor onto the stack, and set it in the backend.
+ *
+ * A local copy of the cursor data will be made, so the original surface
+ * can be safely freed afterwards.
+ *
+ * @param surf New cursor surface.
+ * @param hotspotX Hotspot X coordinate.
+ * @param hotspotY Hotspot Y coordinate.
+ * @param keycolor Color value for the transparent color. This cannot exceed
+ * the maximum color value as defined by format.
+ * Does nothing if mask is set.
+ * @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 mask Optional pointer to cursor mask containing values from the CursorMaskValue enum.
+ *
+ * @note It is acceptable for the surface to be empty. It is sometimes
+ * useful to push a "dummy" cursor and modify it later. The
+ * cursor will be added to the stack, but not to the backend.
+ */
+ void pushCursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const byte *mask = nullptr);
/**
* Pop a cursor from the stack, and restore the previous one to the
@@ -118,6 +140,25 @@ public:
*/
void replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = nullptr, const byte *mask = nullptr);
+ /**
+ * Replace the current cursor on the stack.
+ *
+ * If the stack is empty, the cursor is pushed instead. This is a slightly
+ * more optimized way of popping the old cursor before pushing the new one.
+ *
+ * @param surf New cursor surface.
+ * @param mask New cursor mask data.
+ * @param hotspotX Hotspot X coordinate.
+ * @param hotspotY Hotspot Y coordinate.
+ * @param keycolor Color value for the transparent color. This cannot exceed
+ * the maximum color value as defined by format.
+ * Does nothing if mask is set.
+ * @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 mask Optional pointer to cursor mask containing values from the CursorMaskValue enum.
+ */
+ void replaceCursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const byte *mask = nullptr);
+
/**
* Replace the current cursor on the stack.
*
@@ -215,23 +256,20 @@ private:
~CursorManager();
struct Cursor {
- byte *_data;
+ Surface _surf;
byte *_mask;
bool _visible;
- uint _width;
- uint _height;
int _hotspotX;
int _hotspotY;
uint32 _keycolor;
- Graphics::PixelFormat _format;
bool _dontScale;
uint _size;
- // _format set to default by Graphics::PixelFormat default constructor
- Cursor() : _data(0), _mask(0), _visible(false), _width(0), _height(0), _hotspotX(0), _hotspotY(0), _keycolor(0), _dontScale(false), _size(0) {}
+ // _surf set to default by Graphics::Surface default constructor
+ Cursor() : _mask(0), _visible(false), _hotspotX(0), _hotspotY(0), _keycolor(0), _dontScale(false), _size(0) {}
- Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask);
+ Cursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const byte *mask);
~Cursor();
};
Commit: 38ffb065f5f7d7868b6a9ee0c50823f6038748cd
https://github.com/scummvm/scummvm/commit/38ffb065f5f7d7868b6a9ee0c50823f6038748cd
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-09T13:12:06+02:00
Commit Message:
MADE: Use new CursorMan with cursor surface
Changed paths:
engines/made/graphics.cpp
engines/made/scriptfuncs.cpp
diff --git a/engines/made/graphics.cpp b/engines/made/graphics.cpp
index adaad7a992c..9ecc5d77693 100644
--- a/engines/made/graphics.cpp
+++ b/engines/made/graphics.cpp
@@ -72,6 +72,7 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
960, 961, 962, 963
};
+ uint16 pitch = surface.pitch;
uint16 width = surface.w;
uint16 height = surface.h;
@@ -175,11 +176,12 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
*destPtr = lineBuf[x + y * 320];
destPtr++;
}
+ destPtr += pitch - width;
}
} else {
for (int y = 0; y < 4 && height > 0; y++, height--) {
memcpy(destPtr, &lineBuf[y * 320], width);
- destPtr += width;
+ destPtr += pitch;
}
}
diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp
index d8cc3578b20..195e1360b09 100644
--- a/engines/made/scriptfuncs.cpp
+++ b/engines/made/scriptfuncs.cpp
@@ -580,7 +580,7 @@ int16 ScriptFunctions::sfLoadMouseCursor(int16 argc, int16 *argv) {
PictureResource *flex = _vm->_res->getPicture(argv[2]);
if (flex) {
Graphics::Surface *surf = flex->getPicture();
- CursorMan.replaceCursor(surf->getPixels(), surf->w, surf->h, argv[1], argv[0], 0);
+ CursorMan.replaceCursor(*surf, argv[1], argv[0], 0);
_vm->_res->freeResource(flex);
}
return 0;
Commit: 8e1aa562a3b330703e5299a3badac82b0f8c8fef
https://github.com/scummvm/scummvm/commit/8e1aa562a3b330703e5299a3badac82b0f8c8fef
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-09T13:12:06+02:00
Commit Message:
ASYLUM: Use new CursorMan with cursor surface
Changed paths:
engines/asylum/system/cursor.cpp
diff --git a/engines/asylum/system/cursor.cpp b/engines/asylum/system/cursor.cpp
index de0ddf72271..7b9ee482d13 100644
--- a/engines/asylum/system/cursor.cpp
+++ b/engines/asylum/system/cursor.cpp
@@ -95,12 +95,7 @@ void Cursor::update() {
Common::Point hotspot = getHotspot(_currentFrame);
GraphicFrame *frame = _cursorRes->getFrame(_currentFrame);
- CursorMan.replaceCursor((byte *)frame->surface.getPixels(),
- frame->surface.w,
- frame->surface.h,
- hotspot.x,
- hotspot.y,
- 0);
+ CursorMan.replaceCursor(frame->surface, hotspot.x, hotspot.y, 0);
}
void Cursor::setState(const Common::Event &evt) {
Commit: 8363aeacef38a935ea7f84381dd20c2c2750d4c5
https://github.com/scummvm/scummvm/commit/8363aeacef38a935ea7f84381dd20c2c2750d4c5
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-09T13:12:06+02:00
Commit Message:
ASYLUM: Use standard surface handling
This reverts commit 39c53260 because it is no longer needed - cursor
surfaces are now safely handled. This also opens door to optimized
functions from the Graphics library.
Changed paths:
engines/asylum/system/graphics.cpp
engines/asylum/system/screen.cpp
diff --git a/engines/asylum/system/graphics.cpp b/engines/asylum/system/graphics.cpp
index 71f5bb9fcb5..2ca3a0c1bfe 100644
--- a/engines/asylum/system/graphics.cpp
+++ b/engines/asylum/system/graphics.cpp
@@ -57,7 +57,7 @@ bool GraphicResource::load(ResourceId id) {
void GraphicResource::clear() {
for (uint32 i = 0; i < _frames.size(); i++) {
- delete[] (byte*)_frames[i].surface.getPixels();
+ _frames[i].surface.free();
}
_frames.clear();
@@ -141,9 +141,10 @@ void GraphicResource::init(byte *data, int32 size) {
uint16 width = READ_LE_UINT16(dataPtr);
dataPtr += 2;
- _frames[i].surface.init(width, height, width, new byte[width * height], Graphics::PixelFormat::createFormatCLUT8());
-
- memcpy(_frames[i].surface.getPixels(), dataPtr, (size_t)(width * height));
+ if (width > 0 && height > 0) {
+ _frames[i].surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ _frames[i].surface.copyRectToSurface(dataPtr, width, 0, 0, width, height);
+ }
}
}
diff --git a/engines/asylum/system/screen.cpp b/engines/asylum/system/screen.cpp
index 8cd593dcada..10a44e01e6e 100644
--- a/engines/asylum/system/screen.cpp
+++ b/engines/asylum/system/screen.cpp
@@ -1142,16 +1142,16 @@ void Screen::bltMasked(byte *srcBuffer, byte *maskBuffer, int16 height, int16 wi
void Screen::blt(Common::Rect *dest, GraphicFrame *frame, Common::Rect *source, int32 flags) {
if (_useColorKey) {
- copyToBackBufferWithTransparency((byte *)frame->surface.getPixels() + (source->top * frame->surface.w + source->left),
- frame->surface.w,
+ copyToBackBufferWithTransparency((byte *)frame->surface.getBasePtr(source->left, source->top),
+ frame->surface.pitch,
dest->left,
dest->top,
(uint16)source->width(),
(uint16)source->height(),
(bool)(flags & kDrawFlagMirrorLeftRight));
} else {
- copyToBackBuffer((byte *)frame->surface.getPixels() + (source->top * frame->surface.w + source->left),
- frame->surface.w,
+ copyToBackBuffer((byte *)frame->surface.getBasePtr(source->left, source->top),
+ frame->surface.pitch,
dest->left,
dest->top,
(uint16)source->width(),
@@ -1161,32 +1161,22 @@ void Screen::blt(Common::Rect *dest, GraphicFrame *frame, Common::Rect *source,
}
void Screen::bltFast(int16 dX, int16 dY, GraphicFrame *frame, Common::Rect *source) {
+ if (!frame->surface.getPixels() || source->width() == 0 || source->height() == 0)
+ return;
+
if (_useColorKey) {
- copyToBackBufferWithTransparency((byte *)frame->surface.getPixels() + (source->top * frame->surface.w + source->left),
- frame->surface.w,
- dX,
- dY,
- (uint16)source->width(),
- (uint16)source->height());
+ _backBuffer.copyRectToSurfaceWithKey(frame->surface, dX, dY, *source, 0x00);
} else {
- copyToBackBuffer((byte *)frame->surface.getPixels() + (source->top * frame->surface.w + source->left),
- frame->surface.w,
- dX,
- dY,
- (uint16)source->width(),
- (uint16)source->height());
+ _backBuffer.copyRectToSurface(frame->surface, dX, dY, *source);
}
}
void Screen::copyToBackBuffer(const byte *buffer, int32 pitch, int16 x, int16 y, uint16 width, uint16 height, bool mirrored) {
- byte *dest = (byte *)_backBuffer.getPixels();
+ if (!buffer || width == 0 || height == 0)
+ return;
if (!mirrored) {
- while (height--) {
- memcpy(dest + y * _backBuffer.pitch + x, buffer, width);
- dest += 640;
- buffer += pitch;
- }
+ _backBuffer.copyRectToSurface(buffer, pitch, x, y, width, height);
} else {
error("[Screen::copyToBackBuffer] Mirrored drawing not implemented (no color key)");
}
More information about the Scummvm-git-logs
mailing list