Sign in to follow this  

Steps for multi-platform?

This topic is 829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I have a tiny game engine made in Java and it is solely for Android. I plan to go back and refactor adding features and what not. but one big thing I would like to do is make it multi-platform. Be able to code once and then build accross PC, iOS, Android, etc

 

I kind of feel like a whole rewrite will be needed. but I'm wondering what would be the steps in order to do this (make my engine multi platform)?

I have a few ideas but I'm not sure how correct they are

 

1. I would need to write my 'core' classes in C++ / C. Classes like Rectangle and its intersect method would fall under here.

 

2. Anything that would be platform dependant would have to be done in some native language. EG: Android would be Java and iOS would be Objective-C. Things like using the Game Center or handling phone calls would fall here

 

3. If I wanted to use OpenGL would that fall under something I cold do under my 'core' lib or would it have to be platform specific code?

Edited by noodleBowl

Share this post


Link to post
Share on other sites

code once and then build accross PC, iOS, Android

They are very different platforms.

 

The easiest way to do this is to target an intermediate platform that works on each system.  

 

Unity currently does this.  Unreal has some limited progress with this, but they are improving. Some companies have invested in their own home-grown engines that also work across those platforms.

 

A much harder way to do it is to work with a bunch of intermediate libraries that abstract away platform-specific dependencies.  You might use Cocos-3dx for graphics, OpenAL for audio, something else for file system abstraction, something else for networking abstraction, something else for user input abstractions. This is much more work than picking up a single existing engine.  

 

Or, if you plan on spending your days working on engine parts for personal learning rather than real products, you can start writing your own cross-platform engine, an abstract game engine that works on the selected projects. Basically then you're re-inventing what Unity and Unreal are working on, and it is just you working alone rather than teams of professionals.

Share this post


Link to post
Share on other sites

Or, if you plan on spending your days working on engine parts for personal learning rather than real products, you can start writing your own cross-platform engine, an abstract game engine that works on the selected projects. Basically then you're re-inventing what Unity and Unreal are working on, and it is just you working alone rather than teams of professionals.


This is what I'm more curious about. I want to know "how its done" for lack of better words. How are they able to build for multiple platforms. This I only understand a little and I am unsure where to start.

Are my bullets points close or am I way off?
How does one language like C/C++ make the transition to running Objective C, Java, etc

Share this post


Link to post
Share on other sites

1/2 are pretty accurate.

With 3 - if you're going to use OpenGL everywhere, then it's core/portable code... otherwise it's platform specific code. IMHO, your OpenGL|ES code for android will be quite different than your OpenGL code for desktops, so I would treat it as platform-specific code.

 

Anything platform-specific should be isolated into it's own files. The method I usually use is to define an interface in a header file (my own cross-platform API), and then I implement that in one file per platform -- e.g. widget.h, widget_xbone.cpp, widget_ps4.cpp, etc...

 

As for mixing languages, that depends on the language.

Typically, C is "the universal language" that everything can talk to. If you write a C function, you'll be able to call it from C++, Java, C#, ObjC, etc... It's easy to make C-wrappers around C++ code, so that's one way to allow Java/etc to call your C++ functions.

As for the other direction, e.g. C++->Java, this varies a lot depending on the language being used.

 

If you need to do this, treat it like any other cross-platform code. e.g. widget.h might contain regular portable C++ code in it, but widget_xbone.cpp might contain some Microsoft nonsense that calls out to a different language, like C# or C++/CX.

Share this post


Link to post
Share on other sites

1/2 are pretty accurate.


I have questions. The terribly broad question: how do I even do this?

For example lets say I have this "raw" Rectangle Class.
I say "raw" because it is not written for consumption by Java, Objective-C, etc. At least to my knowledge
 
//Rectangle Header
class Rectangle
{
	public:
		int x;
		int y;
		int width;
		int height;

                void Init();
		int getWidth();
};


//In Rectangle.cpp
#include "Rectangle.h"
Rectangle::Rectangle()
{
        x = 0;
        x = 0;
        width = 64;
        height = 64;
}

int Rectangle::getWidth()
{
	return width;
}

Now lets say for example sake, I'm first working on my Android cross-platformness. (At this point I'm kind of totally lost but..)
Do I now need a wrapper for my Rectangle class?
//C++ JNI wrapper code
#include <jni.h>
#include <Rectangle.h>

extern "C"
{

      JNIEXPORT void JNICALL Java_com_my_package_RectangleWrapper_Init(JNIEnv *env, jobject obj)
      {
	   Rectangle *rect = new Rectangle();
	   obj->_Ptr = (long) rect;
      }

      JNIEXPORT jint JNICALL Java_com_my_package_RectangleWrapper_getWidth (JNIEnv *env, jobject obj)
      {
            return obj.getWidth();
      }
}

//Java code wrapper
public class RectangleWrapper
{
    private long _ptr;
    private native init();
    public native int getWidth();

    public Rectangel()
    {
        Init();
    }

}
Would this also mean that I need a getter for each variable I wanted to access?
Meaning I could never do this
Rectangle r = new Rectangle();
r.Init(); 
int x = r.x;
Edited by noodleBowl

Share this post


Link to post
Share on other sites

Do I now need a wrapper for my Rectangle class?

Probably not. The bulk of your game will be cross-platform code. The platform-specific parts should be quite small. Moreover, only a tiby part of the platform-specific code is forced to use Java/Obj-C.
You only need wrappers if the platform-specific, non-C/C++ parts of the code (i.e. the tiny part of the small part!) need to use that class.

Share this post


Link to post
Share on other sites

Probably not. The bulk of your game will be cross-platform code. The platform-specific parts should be quite small. Moreover, only a tiby part of the platform-specific code is forced to use Java/Obj-C.
You only need wrappers if the platform-specific, non-C/C++ parts of the code (i.e. the tiny part of the small part!) need to use that class.


For some reason I can't wrap my head around this. I understand what you are saying, but at the same time I do not?
I'm trying to think out how this is done, but since I have not done this before it's kind of rough.
 

I guess what I'm trying to say is, would it be more like this?

 

 
The game logic is all in the C/C++ area. What I mean by game logic is all of my game object classes and how they function. So I have my player and how it updates, I have my goblin enemy and how it updates, I have my rocketship and how it updates, and so on so forth. Also all these objects are updated on this side of the fence, the C/C++ side
 

 

Then there is the platform specific code, these things are like how to get a high resolution timer, rendering calls, input calls such as getting touch points or accelerometer data. These are where things get shaky for me, but I would think that these things reside on the C/C++ side and call out to Java, Object-C, or etc side of things
 
For example if I wanted to get a Touch Point to see if a user has their thumb down on the left side of the screen

 
//On theC/C++ side
void Player::Update()
{
     TouchPointInfo info = inputController.getTouchPointInfo(); // Calls out to the platform specific code (Java, Objective-C, or etc)
     for(int i = 0; i < info.activePointsCount; ++i)
     {
          if(LeftScreenBox.contains(inputController.activeTouchPoints[i])
               position -= 5.0f;
     }
}

 

 
The call to inputController.getTouchPointInfo() would cross over from the C/C++ side to the Java, Objective-C, or etc side

Am I thinking right or is this completely wrong / not how things should be done?

Share this post


Link to post
Share on other sites

This topic is 829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this