[Scummvm-devel] Backend modularization (ATTN porters)

Max Horn max at quendi.de
Sun Oct 22 17:43:14 CEST 2006

Hi folks,

this email is meant to explain the backend modifications that have  
just hit HEAD in the repository. They break all backends except the  
SDL one for now, but I hope all backends will very soon be fixed up  
by you guys. With the explanations in this email, it should hopefully  
be a matter of 10 minutes or so. And remember, if you run into  
troubles, we are out here to help you with them :-).

One tidbit to keep in mind for the future: Your custom initBackend()  
method should always invoke the parent's one, unless you have very  
good reasons not to (and usually, it'll be better to fix those  
reasons, contact me if you are in doubt).

The changes are part of the backend modularization effort (see also  
<http://wiki.scummvm.org/index.php/Modular_Backends>). Basically, we  
want to make it possible for backends to hook up into and modify  
higher level functionality, w/o forcing backends to do so. As an  
example, view the TimerManager: Right now, every backend has to  
provide a simple method, setTimerCallback(), and that's it. Easy to  
do; but if you want to implement timers different (see the MorphOS  
backend), you have to modify code outside backends/, and insert  
#ifdef's etc..
So instead, we now allow (and force!) backends to return a  
TimerManage instance of their own. Most backends will just want to  
return the good old DefaultTimerManager (adding only a few lines of  
code), but if they wanted to, they now *could* use a custom  
An existing example for this is the SavefileManager. Another is the  
Audio::Mixer. More will follow, see also the Wiki for a list of ideas.


The quick solution to get your backend compiling again (if you  
already provide a custom getSavefileManager() implementation, take  
that into account; and make sure that your getSavefileManager()  
always returns the same object, and does *not* use "new" to create a  
new one each time. If it does, it should be trivial for you to fix it  
by adapting the code given below):

1) Add some new members to your backend:
    Common::SaveFileManager *_savefile;
    Audio::Mixer *_mixer;
    Common::TimerManager *_timer;

2) Also add these typedefs to your class (they used to be part of  
   typedef void (*SoundProc)(void *param, byte *buf, int len);
   typedef int (*TimerProc)(int interval);

3) Add code to init them to your initBackend() method (or any other  
place you feel suitable for this, e.g. your constructor or your main 
()). Typically, that would be:

   #include "backends/saves/default/default-saves.h"
   #include "backends/timer/default/default-timer.h"
   #include "sound/mixer.h"
   static int timer_handler(int t) {
     DefaultTimerManager *tm = (DefaultTimerManager *)g_system- 
     return tm->handler(t);
   _savefile = new DefaultSaveFileManager();
   _mixer = new Audio::Mixer();
   _timer = new DefaultTimerManager();
   setSoundCallback(Audio::Mixer::mixCallback, _mixer);
   setTimerCallback(&timer_handler, 10);

4) Add these methods to your code:

Common::SaveFileManager *YOUR_OSystem::getSavefileManager() { return  
_savefile; }
Audio::Mixer * YOUR_OSystem::getMixer() { return _mixer; }
Common::TimerManager * YOUR_OSystem::getTimerManager() { return  
_timer; }

5) Depending on your backend, you might want to add code to unhook  
and delete these objects to your destructor / quit() method.

That's it!


Essentially, you have to provide getSavefileManager, getMixer and  
getTimerManager implementations following the correct semantics. In  
exchange, you may be able to remove setSoundCallback,  
clearSoundCallback and setTimerCallback, and hook up the mixer and  
the timer manager in a way that suits you best. Oh, and get rid of  
the nasty timer_handler() function, too.

I will soon partially realize this for the SDL backend.


P.S.: Another nice side effect of all this is of course that Torbjörn  
has to recompile everything once again :)

More information about the Scummvm-devel mailing list