[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