2
\$\begingroup\$

Lets say I want a game to be able to run with SDL, Allegro, on Game parks or Tiny Arcade and I don't want to recode everything everytime I port my game.

The C and C++ language separate definition in .h files and source in .c files. My teacher said it could be possible use the same .h declaration file but have different .c implementation files.

So in theory I could write something like this in the .h (the syntax is not perfect)

typedef myBitmapStruct; void myBlittingFunction ( myBitmapStruct bmp, int x, int y );

Then I could have different .c for each game library. myBitmapStruct will refer to a BITMAP in the allegro implementation, or an sdl_surface in the SDL implementation, etc.

So in theory I think it could work, in practice it might lead to optimization issues. Since first it needs an additional method call because library functions are encapsulated. Second it might been additional code to make conversion or adjustments. For example allegro 5 use an on grid coordinate system, so 0.5 must be added to any x, y coordinates passed in parameter.

Do you think it could be recommended to do a such universal interface?

Did other people already attempted to do this before?

\$\endgroup\$
2
\$\begingroup\$

While it is true that SDL already provides support for multiple platforms, it is of course possible to build another layer on top to abstract the specifics of SDL away from the rest of your code. We do the same in our engine, because SDL doesn't support all of our targets. Similarly, our renderer has an internal abstraction layer so we can support Vulkan, DirectX 12 and potentially other graphics APIs.

This kind of layering is bog standard in game engines. I wouldn't worry too much about the performance implications. Yes, there is a cost incurred with every additional (virtual) function call and those coordinate conversions aren't strictly free... but this overhead is probably insignificant in the grand scheme of things.

In my experience, the gain of having these abstractions (namely the option to switch an underlying API out if/when needed) generally far outweighs the performance cost.

\$\endgroup\$
  • \$\begingroup\$ Also, any set of operations that can be batched, should be, so that the costs of crossing and recrossing that boundary are minimised. Just a heads up for the OP if he decides to go this route. \$\endgroup\$ – Engineer Jul 23 '18 at 9:15
1
\$\begingroup\$

What you are suggesting to do here is actually what a library like Allegro or SDL is doing for you.

SDL, for example:

officially supports Windows, Mac OS X, Linux, iOS, and Android. Support for other platforms may be found in the source code.

SDL provides you with a blit function, which is implemented differently depending on which operating system you are compiling for. That means a game which uses SDL can be compiled for every one of these operating systems (as long as it doesn't use any operating-system dependent features outside of the SDL library).

Adding another abstraction layer on top of your game library would only make sense if you want to support a large number of platforms and just can't find a library which supports all of them. Or you could just as well write your own implementation of the SDL interface for that one obscure platform and link your application against that library when compiling for it.

\$\endgroup\$
0
\$\begingroup\$

I see your point.

Or you could just as well write your own implementation of the SDL interface for that one obscure platform and link your application against that library when compiling for it.

In that case it would make more sense this way. But I might need understand the low level logic of that platform.

For example: The Gamepark has an SDK called Mirko SDK designed for game programmers. It makes sense to call Mirko from my source code, but it does not make sense to call Mirko from SDL (high level lib calling an high level lib). I would be more logical to extract the low level code in Mirko and make an SDL "driver" for it. But I would need deep understanding of the game park which I don't

What I proposed above was an interface that calls high level libraries, but it indeed add an additional call. By thinking about it, it could be more suitable to use C macro system. As it replaces code instead of calling code. I understand that macro are not perfect and could lead to errors, but that could be an alternative solution.

\$\endgroup\$
  • \$\begingroup\$ It's not clear whether this post is meant to provide an answer to your original question. If you want to clarify your question, please use the Edit link on the question itself. If you'd like to reply to an answer you've received, use the Comment button on that answer. Because of the Q&A format used here, Answers are only for when you're trying to provide a solution. \$\endgroup\$ – DMGregory Jul 23 '18 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.