Difference between revisions of "HOWTO-Backends"

From ScummVM :: Wiki
Jump to navigation Jump to search
(→‎Step by step: This page was (is) heavily outdated -- made some fixes)
 
(16 intermediate revisions by 10 users not shown)
Line 4: Line 4:
But if you have determined that a new backend is what you need, the following should hopefully help you a bit with that. Feedback is welcome :-).
But if you have determined that a new backend is what you need, the following should hopefully help you a bit with that. Feedback is welcome :-).


I will assume that you are at least roughly familiar with ScummVM, and have a fresh checkout of our Subversion repository. Note that it's strongly adviced to base your work on the current development version of ScummVM, and not on a release version. This will ease integration of your work.
I will assume that you are at least roughly familiar with ScummVM, and have a fresh checkout of our source code repository. Note that it's strongly advised to base your work on the current development version of ScummVM, and not on a release version. This will ease integration of your work.




=== Overview ===
=== Overview ===
Essentially, you will have to implement a subclass of the OSystem class. Our Doxygen documentation is your friend and should hopefully explain enough about this, see here: http://scummvm.org/docs/doxygen/html/classOSystem.php.  
Essentially, you will have to implement a subclass of the OSystem class. Our Doxygen documentation is your friend and should hopefully explain enough about this, see [https://doxygen.scummvm.org/d2/d38/class_o_system.html OSystem class].  


You also need to either hook yourself into the regular ScummVM build system, or provide your own. Finally, you need to make ScummVM aware of your new backend by updating a couple source files (see below).
You also need to either hook yourself into the regular ScummVM build system, or provide your own. Finally, you need to make ScummVM aware of your new backend by updating a couple source files (see below).


=== Step by step ===
=== Step by step ===
In the following I assume your port is named "foobar" (very clever, isn't it? :-).
In the following I assume your port is named "foobar" (very clever, isn't it? :-)).


# Create a new <code>backends/platform</code> subdirectory matching your engines name, i.e. <tt>backends/foobar/</tt>
# Create a new <code>backends/platform</code> subdirectory matching your port name, i.e. <tt>backends/platform/foobar/</tt>.
# Populate the new directory as you need to. If you want to use our regular build system, you will want to provide <tt>backends/foobar/module.mk</tt> file. Take a look at <code>backends/platform/sdl/module.mk</code> for an example.
# Populate the new directory as you need to. If you want to use our regular build system, you will want to provide a <tt>backends/platform/foobar/module.mk</tt> file. Take a look at <code>backends/platform/sdl/module.mk</code> for an example.
# Subclass OSystem. You could copy the content of <tt>backends/platform/null/null.cpp</tt> to <tt>backends/platform/foobar/foobar.cpp</tt> to get a skeleton. As you progress, it might be helpful to look at other backends to learn how they do things.
# Subclass OSystem. You could copy the content of <tt>backends/platform/null/null.cpp</tt> to <tt>backends/platform/foobar/foobar.cpp</tt> to get a skeleton. As you progress, it might be helpful to look at other backends to learn how they do things.
# Make sure to provide the <tt>main</tt> function in your backend (the actual main function of ScummVM is <tt>scummvm_main</tt>, which your backend must invoke at some point).
# Make sure to provide the <tt>main</tt> function in your backend (the actual main function of ScummVM is <tt>scummvm_main</tt>, which your backend must invoke at some point).
# Instantiate OSystem class and assign it to <tt>g_system</tt>, do that before calling <tt>scumm_main</tt>
# Instantiate the OSystem class and assign it to <tt>g_system</tt>, do that before calling <tt>scumm_main</tt>.
# Deinit properly after calling <tt>scumm_main</tt>, particularly call <tt>g_system->quit()</tt>
# Deinit properly after calling <tt>scumm_main</tt>, particularly call <tt>g_system->destroy()</tt>.
# If appropriate, edit <tt>configure</tt> to add your backend (this is only necessary if you are going to use the "./configure && make" build system).
# If appropriate, edit <tt>configure</tt> to add your backend (this is only necessary if you are going to use the "./configure && make" build system).


==== Example of minimal main() ====
==== Example of minimal main() ====
  int main(int argc, char *argv[]) {
<syntaxhighlight lang="cpp">int main(int argc, char *argv[]) {
      g_system = new OSystem_Foobar();
// Create our OSystem instance
      assert(g_system);
    g_system = new OSystem_Foobar();
     
    assert(g_system);
      // Invoke the actual ScummVM main entry point:
   
      int res = scummvm_main(argc, argv);
    // Invoke the actual ScummVM main entry point:
      g_system->quit();
    int res = scummvm_main(argc, argv);
      return res;
  }


// Free OSystem
g_system->destroy();
    return res;
}</syntaxhighlight>


That's it. The difficult part is of course writing the OSystem subclass. More on that in the next section!
That's it. The difficult part is of course writing the OSystem subclass. More on that in the next section!


=== Subclassing OSystem ===
=== Subclassing OSystem ===
TODO: This section is meant to give some specific hints on creating a useful OSystem subclass. For now I can't really think of anything useful besides the obvious, and besides what we already say in other places... Take a look at http://scummvm.org/docs/doxygen/html/classOSystem.php which contains lots of useful information. Also take a look at null.cpp to see what you have to implement, and peek at the SDL backend (which is our main backend and thus kind of a reference for all the others). And finally, take a look at <tt>common/system.h</tt> to see which methods are pure abstract, and thus *must* be implemented by you. Oh and of course: You can always talk to us on IRC or via email :-).
TODO: This section is meant to give some specific hints on creating a useful OSystem subclass. For now I can't really think of anything useful besides the obvious, and besides what we already say in other places... Take a look at [https://doxygen.scummvm.org/d2/d38/class_o_system.html OSystem class] which contains lots of useful information. Also take a look at null.cpp to see what you have to implement, and peek at the SDL backend (which is our main backend and thus kind of a reference for all the others). And finally, take a look at <tt>common/system.h</tt> to see which methods are pure abstract, and thus '''must''' be implemented by you. Oh and of course: You can always talk to us on [[IRC Channel|IRC]] or via [[Mailing lists|email]] :-).
 


=== Misc notes ===
=== Implementing subsystems ===
There is [[Small Devices Backend]] in the works which is planned to be common for all devices with limited resources. If you are working on a backend for such a system, you may want to take a look on that page!
* [[HOWTO-Backends/File system]]
* [[HOWTO-Backends/Mutexes and Timers]]
* [[HOWTO-Backends/Graphics]]
* [[HOWTO-Backends/Events]]
* [[HOWTO-Backends/Audio]]
* [[HOWTO-Backends/Plugins]]
* [[HOWTO-Backends/Miscellaneous]]


==== updateScreen() method ====
==== Testing your backend ====
updateScreen() method is called by an engine when it finished drawing something on the screen. It may happen quite often, up to several hundred times per second, but some devices have restriction on how many times per second screen bliting takes place. For example, some NTSC version can not physically update more often that 60Hz, and attempts to make it more often will result in the machine hang.
We have a special game engine, called 'testbed'. Its only purpose is to perform series of tests which help backend authors to see correctness of their implementation.


If you're writing a backend for such system, you may use code like this:
To run the game, point ScummVM to directory <tt>&lt;scummvm sources root&gt;/dists/engine-data/testbed-audiocd-files/</tt> and then run. Follow the on-screen instructions.


  void updateScreen() {
=== Misc notes ===
      uint32 newTime = getMillis();
There is a [[Small Devices Backend]] in the works which is planned to be common for all devices with limited resources. If you are working on a backend for such a system, you may want to take a look on that page!
      if (newTime - _oldTime < 1000 / MAX_FPS)
          return;
 
      _oldTime = newTime;
 
      // do actual screen update
  }
 
That should do the trick for you,

Latest revision as of 21:39, 19 April 2022

Introduction

This page is meant as a mini-HOWTO which roughly outlines the steps needed to add a new backend (port) to ScummVM. Before you embark on this quest, however, you should first check if one of the existing backends already suits your needs. In particular the SDL backend already supports many platforms, since SDL itself is quite portable.

But if you have determined that a new backend is what you need, the following should hopefully help you a bit with that. Feedback is welcome :-).

I will assume that you are at least roughly familiar with ScummVM, and have a fresh checkout of our source code repository. Note that it's strongly advised to base your work on the current development version of ScummVM, and not on a release version. This will ease integration of your work.


Overview

Essentially, you will have to implement a subclass of the OSystem class. Our Doxygen documentation is your friend and should hopefully explain enough about this, see OSystem class.

You also need to either hook yourself into the regular ScummVM build system, or provide your own. Finally, you need to make ScummVM aware of your new backend by updating a couple source files (see below).

Step by step

In the following I assume your port is named "foobar" (very clever, isn't it? :-)).

  1. Create a new backends/platform subdirectory matching your port name, i.e. backends/platform/foobar/.
  2. Populate the new directory as you need to. If you want to use our regular build system, you will want to provide a backends/platform/foobar/module.mk file. Take a look at backends/platform/sdl/module.mk for an example.
  3. Subclass OSystem. You could copy the content of backends/platform/null/null.cpp to backends/platform/foobar/foobar.cpp to get a skeleton. As you progress, it might be helpful to look at other backends to learn how they do things.
  4. Make sure to provide the main function in your backend (the actual main function of ScummVM is scummvm_main, which your backend must invoke at some point).
  5. Instantiate the OSystem class and assign it to g_system, do that before calling scumm_main.
  6. Deinit properly after calling scumm_main, particularly call g_system->destroy().
  7. If appropriate, edit configure to add your backend (this is only necessary if you are going to use the "./configure && make" build system).

Example of minimal main()

int main(int argc, char *argv[]) {
	// Create our OSystem instance
    g_system = new OSystem_Foobar();
    assert(g_system);
    
    // Invoke the actual ScummVM main entry point:
    int res = scummvm_main(argc, argv);

	// Free OSystem
	g_system->destroy();

    return res;
}

That's it. The difficult part is of course writing the OSystem subclass. More on that in the next section!

Subclassing OSystem

TODO: This section is meant to give some specific hints on creating a useful OSystem subclass. For now I can't really think of anything useful besides the obvious, and besides what we already say in other places... Take a look at OSystem class which contains lots of useful information. Also take a look at null.cpp to see what you have to implement, and peek at the SDL backend (which is our main backend and thus kind of a reference for all the others). And finally, take a look at common/system.h to see which methods are pure abstract, and thus must be implemented by you. Oh and of course: You can always talk to us on IRC or via email :-).

Implementing subsystems

Testing your backend

We have a special game engine, called 'testbed'. Its only purpose is to perform series of tests which help backend authors to see correctness of their implementation.

To run the game, point ScummVM to directory <scummvm sources root>/dists/engine-data/testbed-audiocd-files/ and then run. Follow the on-screen instructions.

Misc notes

There is a Small Devices Backend in the works which is planned to be common for all devices with limited resources. If you are working on a backend for such a system, you may want to take a look on that page!