Skip to content

OLC PGE Mobile 2.0

John Galvin edited this page Oct 6, 2024 · 14 revisions

Overview

This wiki gives a full overview of every function and method used in the OLC PGE Mobile 2.0.

Definitions

TODO : Each function and method within the olcPixelGameEngine_Mobile.cpp will have a link back to this page, so that the developer can access more information on what the function/method does. Add more verbiage

main.cpp

This is the main entry point for any application that uses 'olcPixelGameEngine_Mobile.cpp'. It is from this class you start and create all our your amazing PGE mobile games.

Headers:

To get our OLC PGE Engine up and running on both Android & iOS we need a few headers and some #define. These work together to allow you to just development your application/game using the amazing PGE 2.0 and C++ without having to handle all complicitly under the hood to get your code to work smoothly on both operating systems.

We like to keep things super simple here at the One Lone Coder Community so this is all done and dusted for you :)

  • pch.h Pre-Complied Header, this is used to setup and complied required headers, makes comply times faster, and helps us to ensure the correct sub headers for Android & iOS are complied and ready for you to use. NOTE the iOS pch.h file is handled within the Objective C
  • #include "../_ProjectName_/pch.h" the ProjectName is auto generated, do not change, well you can, but I wouldn't ;)
  • #if defined (__ANDROID__) Complier Talk Tells the complier to use this block of code to for Android Devices
#if defined (__ANDROID__)

#include "../<ProjectName>/pch.h"

#endif //__ANDROID__
  • #if defined (__APPLE__) Complier Talk Tells the complier to use this block of code to for APPLE iOS Devices
  • ios_native_app_glue.h the is a GLUE interface between the PGE Mobile 2.0 and the iOS application.
  • #include <memory> there are a few Smart Pointers needed to get thing running and linking, therefore we include the memory.h here
#if defined (__APPLE__)

#include "ios_native_app_glue.h"
#include <memory>

#endif
  • SIMD (SSE2) is enabled by default for all x86/64 CPUs, and is auto disabled when an ARM/ARM64 CPU is detected
  • #define STBI_NO_SIMD Complier Talk Tells the complier not to use SIMD. This is commented out by default.
  • SIMD/NEON greatly improves the speed of your game
  • NOTE Mobile devices CPU/GPU are very weak compared to their big sisters in computers. SIMD/NEON technology is used to greatly reduce this gap.
//#define STBI_NO_SIMD // Removes SIMD Support
// SIMD greatly improves the speed of your game
  • #if defined(__arm__)||(__aarch64__) Complier Talk Tells the complier to use this block of code when an ARM or ARM64 CPU is detected
  • #define STBI_NEON for ARM/ARM64, Complier Talk Tells the complier to use use Advance SIMD NEON when loading and processing images.
  • Nearly every mobile device today use ARM/ARM64, except of course for the Intel Atom used in most Chrome Books and some Tablets
  • NOTE Mobile devices CPU/GPU are very weak compared to their big sisters in Computers. SIMD/NEON technology is used to greatly reduce this gap.
#if defined(__arm__)||(__aarch64__)

#define STBI_NEON

#endif
  • #define OLC_PGE_APPLICATION Complier Talk Tells the complier to use the olcPixelGameEngine.h as a header-only library, where the header both declares and also defines the bodies of the methods.
  • #define OLC_IMAGE_STB Complier Talk Tells the complier to use STBImage.h for image processing, we need to use this over libpng.h as it supports SIMD/NEON, otherwise, as stated above, things would be too slow.
  • Nearly every mobile device today use ARM/ARM64, except of course for the Intel Atom used in most Chrome Books and some Tablets
  • #include "olcPixelGameEngine_Mobile.h" IMPORTANT: we must include olcPixelGameEngine_Mobile.h not olcPixelGameEngine.h , the mobile edition ; althought contains the same functionality; is very different under the hood.
  • The OLC PGE 2.0 Mobile only supports Android and iOS only.
  • NOTE OLC PGE 2.0 Mobile has support for iOS Apps downloaded from the Apple Store to a MAC only.
#define OLC_PGE_APPLICATION
#define OLC_IMAGE_STB
#include "olcPixelGameEngine_Mobile.h"
  • #define OLC_PGEX_MINIAUDIO Complier Talk Tells the complier to use OLC PEGX Mini Audio for sounds
  • Checkout OLC PGEX MiniAudio Thanks Moro1138
#define OLC_PGEX_MINIAUDIO
#include "olcPGEX_MiniAudio.h"  // Checkout https://github.com/Moros1138/olcPGEX_MiniAudio Thanks Moros1138
  • #include <fstream> Used for saving the SaveState to a file, see add link to OnSaveStateRequested
#include <fstream> // Used for saving the SaveState to a file

Class

To ensure proper cross platform support between Android and iOS it is recommended to keep the class name as PGE_Mobile, This will ensure the iOS can launch the engine correctly, if you change it make the required changes in <TODO: Link> GameViewController.mm in the iOS app to suit.

  • class PGE_Mobile : public olc::PixelGameEngine creates an instance of our game class with a public interface of olc::PixelGameEngine, in short gives us access to all the cool and wonderful functionalities of the Pixel Game Engine

  • PGE_Mobile() { ... } Class constructor. NOTE Never load an image/object from the constructor, always use OnUserCreate() (TODO: Add link to why this can break on iOS)

  • sAppName = "Android/iOS Demo"; Stores the name of your game / application

  • For information on OnUserCreate() , OnUserUpdated() and OnUserDestroy() please see the OLC PGE 2.0 wiki as these are standard PGE 2.0 methods

  • void OnSaveStateRequested() override fires when your application as lost focus and might be destoryed. i.e. An incoming phone call, Text Message, An Alert, anything where the user has moved away from your application.

    • The void OnDestory() override maybe not always fire, as it depends on the current actions of the user. However once the void OnDestory() override is fired it means the OS is about to destroy your application. It is important you save what details you need.
    • void OnSaveStateRequested() override will always be the last method fired, i.e. it will always fire after an OnUserDestory() if requested from the OS.
    • You have limited time to save your game state, save only important information i.e. Player Location, Game Level etc. Do not try to store any memory objects, like Smart Points, Vectors etc, as once an application is destroyed all memory associated with the application is also destroyed.
  • void OnRestoreStateRequested() override { fires when your application loads.

    • Fires when your application loads regardless if the application was destroyed previously.
    • Fires when your application regains focus, i.e. after an incoming call, text message etc
    • Fires before the OnUserCreate()
    • Use this method to reload your game state
  • `void OnLowMemoryWarning() override { , fires when the OS detects it is low on memory

    • This method is fired on all currently active applications
    • Use this method to clean up any unused, leftover or not needed memory (Sprites, Decals, vectors)
    • Use this method to clear any vectors or blocks of memory that can be reloaded later
    • Use this method to save memory to a file
    • If the OS cannot gain back enough memory from its applications it will force close these applications
    • Please follow the steps above to ensure your application is not force closed
    • BTW Most Application Developers never implement this method, and then wonder why their app is closed at random, don't be one them please!
class PGE_Mobile : public olc::PixelGameEngine {

public:

    PGE_Mobile() {
        sAppName = "Android/iOS Demo";
    }

    bool OnUserCreate() override {
         // Load images, objects, sounds etc etc
    }

    bool OnUserUpdate(float fElapsedTime) override {
        // Execute Game Logic fires once a frame
        return true;
    }

    bool OnUserDestroy() override {
        // Fires when the app is about to be destroyed
        return true;
    }

    void OnSaveStateRequested() override {
        // Fires when the app is about to be destroyed
        
    }

   void OnRestoreStateRequested() override {
        // Fires when the app is restored
        
    }

    void OnLowMemoryWarning() override {
        // Fires when the OS is low on memory, reduce your memory usage or risk your app been closed
        
    }



}

Entry points

There are two entry points for Android and iOS respectfully. in order to maintain cross platform compatibility the entry points for both operating systems are different, as both Operation Systems work completely different.

The good news is once you have your entry point setup correctly, as detailed below, everything after this is the same for both Operating Systems.

We like to keep things super simple here at the One Lone Coder Community


Android:

  • #if defined (__ANDROID__) Complier Talk Tells the complier to use this block of code to for Android Devices
#if defined (__ANDROID__)
/*
* Code stuff
*/

#endif //__ANDROID__
  • void Android_main() this is the main entry point of a native application
  • It runs in its own thread, with its own event loop for receiving input events and doing other things.
  • This is now what drives the engine, the thread is controlled from the OS
void android_main(struct android_app* initialstate) {
/*
* Code stuff
*/
}
  • struct android_app* initialstate initalstate allows you to make some more edits to your app before the PGE Engine starts
  • Recommended just to leave it at its defaults, but change it at your own risk
  • to access the Android directly in your code android_app* pMyAndroid = this->pOsEngine.app;
void android_main(struct android_app* initialstate) {
/*
* initialstate stuff
* <TODO> : Create a section for explaining intialstate
*/
}
  • PGE_Mobile demo class instantiation, starts up the PGE Engine
  • demo.Construct(1280, 720, 2, 2, true, false, false); Note it is best to use HD(1280, 720, ? X ? pixel, Fullscreen = true) the engine can scale this best for all screen sizes, without affecting performance... well it will have a very small affect, it will depend on your pixel size. Note: cohesion is currently not working.
  • demo.Start(); Start the application
 PGE_Mobile demo;
 demo.Construct(1280, 720, 2, 2, true, false, false);
 demo.Start(); // Lets get the party started
  • Example:
#if defined (__ANDROID__)

void android_main(struct android_app* initialstate) {

    PGE_Mobile demo;

    demo.Construct(1280, 720, 2, 2, true, false, false);

    demo.Start(); // Lets get the party started

}

#endif

iOS:

  • #if defined (__APPLE__) Complier Talk Tells the complier to use this block of code to for APPLE iOS Devices
#if defined (__APPLE__)
/*
* Code stuff
*/

#endif //__APPLE__
  • int ios_main(IOSNativeApp* pIOSNatvieApp) The is the entry point from the iOS Objective C, called during the start-up of your application
  • Use the objects defined in IOSNativeApp to pass data to the Objective C
  • By Default you must at minimum pass the game construct vars, pIOSNatvieApp->SetPGEConstruct
  • iOS runs in its own threads, with its own event loop for receiving input events and doing other things.
  • This is now what drives the engine, the thread is controlled from the OS
int ios_main(IOSNativeApp* pIOSNatvieApp) {
/*
* Code Stuff
*/
}
  • int ios_main(IOSNativeApp* pIOSNatvieApp) pIOSNatvieApp allows access to the OS App options
  • The iOS will instance your app differently to how Android does it
  • In the iOS it will automatically create the required classes and pointers to get the PGE up and running successfully.
  • IMPORTANT: You must set your class name to PGE_Mobile (see above) always for iOS
  • Don't worry it will not conflict with any other apps that use the same base class name of PGE_Mobile
  • To access the iOS directly in your code auto* pMyApple = this->pOsEngine.app;
int ios_main(IOSNativeApp* pIOSNatvieApp) {
/*
* pIOSNatvieApp-> <TODO> Create section explaining options
*/
}
  • pIOSNatvieApp->SetPGEConstruct(0, 0, 2, 2, true, true, false); Note it is best to use HD(0, 0, ? X ? pixel, Fullscreen = true) the engine can scale this best for all screen sizes, without affecting performance... well it will have a very small affect, it will depend on your pixel size Note: cohesion is currently not working.
  • return EXIT_SUCCESS; You must return EXIT_SUCCESS in order to tell the iOS to start up the engine, you can return EXIT_FAILURE, error codes etc will stop the startup of the engine and the app will exit gracefully
pIOSNatvieApp->SetPGEConstruct(0, 0, 2, 2, true, true, false);
return EXIT_SUCCESS;
  • Example:
#if defined(__APPLE__)

int ios_main(IOSNativeApp* pIOSNatvieApp)
{
    
    pIOSNatvieApp->SetPGEConstruct(0, 0, 2, 2, true, true, false);
    return EXIT_SUCCESS;
}

#endif

Please Note: Although this is considered to be the main entry point, under the hood it is not, the main entry point comes from the phone OS and is used to start up all the threads, memory, smart pointers etc in order for the PGE Engine to start up. The reason we state that main.cpp is the main entry point is to allow cross compatibility with the OLC PGE 2.0 engine for Windows, MAC, Linux, PlayStation and the list goes on.

Clone this wiki locally