KEMBAR78
GRAPHICS: Add support for cursor masks and cursor inverted pixels by elasota · Pull Request #4713 · scummvm/scummvm · GitHub
Skip to content

Conversation

@elasota
Copy link
Contributor

@elasota elasota commented Feb 14, 2023

This adds support for explicit cursor masks instead of key color as well as inverted pixel masks. The third mode (color XOR) is not currently supported by anything, it can in theory be implemented via glLogicOp in OpenGL 2.0 and GLES 2.0 but due to some tough problems with filtering, it's only really possible with either unscaled cursors or by rendering into the framebuffer instead of as an overlay with subpixel precision.

I'm not sure if any games actually use color XOR, it's definitely supported by classic MacOS and in theory could be supported on Windows but based on WDDM documentation, any invert color other than white may be undefined behavior on Windows. So, I'm stubbing it out for completeness and so cursor loading code can try to handle it with a bit more elegance, but that's it.

Copy link
Member

@sev- sev- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice feature. Have only few minor notes and question about support in SurfaceSDL

* Backends supporting this feature allow cursor masks to use mode kCursorMaskInvert in mask values,
* which inverts the destination pixel.
*/
kFeatureCursorMaskInvert,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two values seem to me a bit too granular. Is the engine code expected to feed backends with different cursors based on these inverted mask feature flags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this entry to be a bit more detailed, unfortunately it's even more complicated now, but it is more correct.

Yes, the intent is engine code is supposed to feed different cursors if invert isn't supported because the engine (or cursor loader) will need to decide what color to use for invert pixels if the invert mode that it wants to use isn't supported.

The color invert is because of the complicated Classic MacOS invert semantics. Both Mac and Win, in theory, were designed with blend behavior (Destination AND Mask) XOR Cursor semantics, however in the MacOS default palette, the 0 color is white and the 255 color (or 1 color in BW mode) is black, whereas on Windows it is the opposite. This created a problem because when true color modes were added, the cursor color that is supposed to invert now has a color value of 0, so MacOS in true color modes uses (Destination AND Mask) XNOR Color (which is same as (Destination AND Mask) XOR (NOT Color)), so should some game use that, it is up to the backend to figure out how to render it.

Windows cursors do not support this, in theory the data allows it but the WDDM semantics are that any color with AND mask 1 is only either transparent or inverted, and it is only inverted if the color is white.

bool formatChanged = false;

if (mask)
warning("SurfaceSdlGraphicsManager::setMouseCursor: Masks are not supported");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit sad. Is there a way to support cursor masks in the SurfaceSDL backend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will investigate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I think that will not be an easy addition because with 8-bit cursors it creates an 8-bit SDL surface for the cursor and calls SDL_BlitSurface to draw it, which supports color key but does not support masks. It may be possible to detect an absent color and use that as color key as long as the cursor doesn't contain 256 unique colors AND transparent pixels (which is impossible with a MacOS cursor and highly unlikely with a Win cursor) but doing better than that will require a custom blit.

@elasota elasota force-pushed the cursor-invert-pixels branch from 25c72d9 to e405cbf Compare February 19, 2023 00:07
@sev-
Copy link
Member

sev- commented Feb 19, 2023

This is great. Thank you for addressing all issues.

Further development could be performed in-tree.

@sev- sev- merged commit 325674a into scummvm:master Feb 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants