[Scummvm-devel] Overlay handling (Was: Virtual keyboard code from GSoC 2008)
Max Horn
max at quendi.de
Thu Jan 22 04:01:21 CET 2009
Am 21.01.2009 um 10:31 schrieb Johannes Schickel:
> Max Horn schrieb:
>> There are two major problems with this.
>>
>> 1) The whole vkeybd code runs in its own event loop. If we wanted to
>> show the vkeybd while the game runs, we'd have to redesign this.
>> Like,
>> by setting aside a portion of the screen for the vkeybd, and whenever
>> a click occurs in there, we intercept it.
>>
>
> I guess this one could be handled fairly easily within
> DefaultEventManager. For example it could throw mouse click events
> first
> at an input to VirtualKeyboard and checking if the vkbd has any
> means of
> handling that specific event.
Sure, it's definitely doable. The code "just" has to be rewritten for
that :-). However, is DefaultEventManager really the place for that?
It sure is getting crowded in there. Also, we maybe should just drop
the name DefaultEventManager and call it "EventManager" -- as we keep
adding important functionality in there, we more and more render the
idea of a component based backend obsolete :-/.
I'll sketch an alternative suggestion below, where it fits better.
>> 2) The current overlay code is built around the assumption that the
>> underlying game graphics are frozen. This is yet another thing (of
>> countless others) that would be nice to improve. Some random thoughts
>> on this:
>>
>
> Well actually I'm wondering why we draw it at all on the overlay. We
> could just let backends doing the drawing itself on the real video
> surface or on another overlay which will be merged into the video
> surface last.
[...]
> The downside of letting the backend doing all the drawing is of course
> that we can't easily enable the vkbd code on every backend.
I think that answers your question from above (why the vkeybd is drawn
in the overlay) :-): It made it possible to implement the vkeybd w/o
messing with backends.
Having the vkeybd in its own "vkeybd overlay" atop the regular "GUI
overlay" (and leaving it up to the backend to composit both) certainly
would be appealing -- that would make it easier to use it in GUI
dialogs, for example.
> Also it
> might ugly to have the event code in DefaultEventManager and all the
> drawing must be done by the backend (it gives questions like "how does
> the backend know the position changed?" etc.).
Indeed. If we move the vkeybd compositing code to the backend, then we
should also move the vkeybd handlin code to the backend. Or rather: We
should move the code which *invokes* the rendering & handling code
there. I.e., change the vkeybd code to provide simple APIs that can be
used to quickly vkeybd-enable a backend. From a porters point of view,
it could work like this:
1) The porter adds another "overlay" surface, which, if enabled, is
rendered atop the game screen and the "GUI" overlay. This overlay
could use alpha blending or not; and it would only be as big as
necessary.
2) During startup, the backend instantiates an object of the
hypothetical VirtualKeyboard class (either BuiltinVirtualKeyboard, or
ZIPPackVirtualKeyboard, or whatever). Backend queries the vkeybd for
its preferred size, and resizes the vkeybd overlay accordingly:
VirtualKeyboard *_vkbd;
_vkbd = new BuiltinVirtualKeyboard(this);
Point size = _vkbd->getPreferredSize();
resizeVKOverlay(size);
3) When the "show vkeybd" trigger is received, the vkeybd overlay is
activated, and vkeybd inited
_vkbd->setSurface(_vkbdOverlaySurface);
_vkbd->open(); // Reset vkbd data, draw into the surface
4) All drawing is done by the backend. When a click occurs, it first
checks whether it is on the vkeybd. If so, it passes the click to the
vkeybd. The vkeybd will compute whether a key was hit, and take
appropriate action. In particular, it may redraw part of the vkeybd
surface.
_vkbd->handleClick(pt);
or even
_vkbd->handleEvent(event);
5) In its updateScreen method, the backend redraws the vkbd simply by
rendering the vkbd surface. We could make use of some kind of dirty
rect handling, e.g. by adding a method
List<Rect> VirtualKeyboard::getDirtyRectList()
6) If the user pressed the "send" button, or if we are in "real-time"
mode (meaning that every virtual keystroke is turned into a keyboard
event immediately), then the vkeybd invokes EventManager::pushEvent as
necessary.
6) In addition, the backend probably should invoke the vkeybd at
regular intervals (say in its event loop, and/or in updateScreen), to
allow for effects. Like, if a button is pressed, the vkeybd might want
to toggle it for 50ms or so
...
_vkbd->handleTimer()
...
>
>
> I'm currently unsure on how we should really proceed, but IMHO the
> current overlay sharing approach is definitely not the best way to
> go :-/.
Agreed. A lot about the vkeybd and keymapper code strikes me as "not
the best way to go" ;-).
Cheers,
Max
More information about the Scummvm-devel
mailing list