SlideShare une entreprise Scribd logo
1  sur  28
Porting and Maintaining Your
C++ Game
on Android
(without losing your mind)
Why C++


Cross-Platform support





(Some lesser platforms don’t have a JVM)

Don’t want to use Unity, etc
Existing C++ Codebase
Overview




NDK recap
What goes where? C++ vs Java
Streamlining packaged app data






Eliminating Data Duplication

Compiling multiple architectures
Other quirks we’ve run into
Some downloads info about our apps
NDK

Application.mk

APP_PROJECT_PATH := $(call my-dir)
APP_BUILD_SCRIPT := $(call my-dir)/Android.mk
APP_MODULES
:= GHEngine
APP_OPTIM := release
APP_STL := stlport_static
APP_PLATFORM := android-8
NDK

(static lib)

Android.mk

LOCAL_PATH := $(call my-dir)
LOCAL_CFLAGS := -Wno-psabi
LOCAL_CFLAGS += -D ANDROID
LOCAL_MODULE
:= GHEngine
LOCAL_MODULE_FILENAME := libGHEngine
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../Base
LOCAL_SRC_FILES += ../../../../Base/GHAppRunner.cpp
include $(BUILD_STATIC_LIBRARY)
NDK

Android.mk
(shared lib – loaded by java)
LOCAL_MODULE := libGHEngine
LOCAL_SRC_FILES :=
../../GHEngine/obj/local/armeabi/libGHEngine.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_STATIC_LIBRARIES += libGHEngine
include $(BUILD_SHARED_LIBRARY)
$(shell cp libs/armeabi/libGHBowling.so
../../../GHBowlingBase/libs/armeabi)
NDK
JNI
Loading the C++ Library
public class GHBowlingBaseActivity
extends Activity {
static {
System.loadLibrary("GHBowling");
}
}


Loads the file named libGHBowling.so
NDK
JNI
Java (calling C++)
public class GHEngineInterface {
public native void runNativeFrame();
public native void launchNativeApp(int windowWidth,
int windowHeight,
String externalStoragePath,
int isTablet,int iapIsOn);
//resizeWindow, handleTouchStart, handleTouchEnd, handleTouchPos
//handleAcceleration, handleJavaPause, handleJavaResume,
//handleJavaShutdown,handleBackPressed, calculatePublicKey,
//onInterstitialRewardGranted,onRewardInterstitialAvailabilityChange,
//onInterstitialDismiss, loadFile,handleTextureLoadConfirmed,
//onAdActivation, onAdDeactivation, onIAPPurchase
}
NDK
JNI
C++ (called by Java)
static jobject globalEngineInterface = 0;
extern "C“ __attribute__((visibility("default")))
void
Java_goldenhammer_ghbowlingbase_GHEngineInterface_launchNativeApp
(JNIEnv* env, jobject engineInterface,
jint windowWidth, jint windowHeight,
jstring jExternalStoragePath,
jint isTablet, jint useIAP)
{
globalEngineInterface = env->NewGlobalRef(engineInterface);
//Engine/Game Initialization goes here.
}



When you shut down:
env->DeleteGlobalRef(globalEngineInterface);
NDK
JNI
Java (called by C++)
public class GHEngineInterface
{
public void showInterstitialAd() {
if (mInterstitialHandler != null) {
mInterstitialHandler.showInterstitial();
} else {
onInterstitialDismiss();
}
}
};
NDK
JNI
C++ (calling Java)


GHAndroidInterstitialAd class declaration:
JNIEnv& mJNIEnv;
jobject mEngineInterface;
jmethodID mShowAdMethod;



GHAndroidInterstitialAd ctor:
jclass cls = mJNIEnv.GetObjectClass(mEngineInterface);
mShowAdMethod = mJNIEnv.GetMethodID(cls, "showInterstitialAd", "()V");



GHAndroidInterstitialAd::activate:
mJNIEnv.CallVoidMethod(mJavaObj, mShowAdMethod);
What goes Where?
C++ or Java


C++





Java





All your platform-independent/pre-existing code
Bare minimum wrapper for Android implementation of
platform services
Typical Android platform code
Middleware integration

Can swap middleware vendors of the same service
without touching C++

Exceptions:



OpenGL (initialization in Java, most code in C++ or GLSL)
File I/O (mix of Java, C++)
What Goes Where
Java







OpenGL initialization
Sound through SoundPool
File handle loading through AssetManager
Image loading through BitmapFactory
Google Play, In-App Billing, etc
Ads and other middleware integration




AdMob, AdColony, Chartboost, PlayHaven, Facebook, etc

Input Handling


(touches, accelerometer, buttons/gamepad)
What Goes Where
C++


All your game code




OpenGL rendering code





Ideally 90% of your app
Need to handle reinit after lost device

fopen using file handle from Java
Thin wrapper over JNI calls for
everything else
What Goes Where
Our code distribution.


2800 lines Java



1600 in base project
1200 in master project




Includes middleware integration

50k-150k lines C++



Varies depending on game
6400 Android-specific C++
Eliminating Data Duplication
Problem






Eclipse wants all data underneath
project
We want to reuse data (between
projects) in our own directory structure
We hate maintaining multiple copies of
the same data files.
Eliminating Data Duplication
Solution



Batch file/shell script to copy data
On Mac

cp ../../../../../data/GHBowling/ballrollloop.wav
../../../GHBowling/assets/ballrollloop.wav
cp
../../../../../data/Bowling/GHBowlingAndroid/backwall.jpg ../.
./../GHBowling/assets/backwall.jpg



On Windows

copy ..........dataGHBowlingballrollloop.wav
......GHBowlingassetsballrollloop.wav
copy
..........dataBowlingGHBowlingAndroidbackwall.jpg ...
...GHBowlingassetsbackwall.jpg
Eliminating Data Duplication
Batch File Generation


Tool for initial generation


Looks through set of directories with a specified
order of preference








Some files are different per-platform
We may have Android-specific files
We may not, but we prefer iOS-specific to generic

Downside: some unnecessary files get copied

Maintenance usually done by hand
Packaged App Data
Problem






Data is packaged through Android build
process
All files except those with certain
excluded file extensions (precompressed file types) are
automatically compressed.
Platform-agnostic file reading code
doesn’t know to uncompress: sees
garbage
Excluded file extensions


Source: Android Asset Packaging Tool

/* these formats are already compressed, or don't
compress well */
static const char* kNoCompressExt[] = { ".jpg",
".jpeg", ".png", ".gif", ".wav", ".mp2",
".mp3", ".ogg", ".aac", ".mpg", ".mpeg",
".mid", ".midi", ".smf", ".jet", ".rtttl",
".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp",
".3gpp", ".3g2", ".3gpp2", ".amr", ".awb",
".wma", ".wmv" };
App Data Compression
Solution




One option: forgo Eclipse and pass –0
to the AAPT via command line
(universally or for certain extensions)
What we do

cp
../../../../../data/GHBowlingiOS/arrowpixel.glsl ../
../../GHBowling/assets/arrowpixel.glsl.mp3
Compiling for x86
(or other architectures)


In Application.mk:
APP_ABI := x86 armeabi


Supported values:






armeabi
armeabi-v7a
x86
mips
all
Compiling for x86
Problem


Shared library Android.mk needs to
include the correct static library for each
architecture



For arm: /armeabi/libGHEngine.a
For x86: /x86/libGHEngine.a
Compiling for x86
Solution
include $(CLEAR_VARS)
LOCAL_MODULE := libGHEngine
LOCAL_SRC_FILES :=
../../GHEngine/obj/local/$(TARGET_ARCH_ABI)/libGHEngine.a
include $(PREBUILT_STATIC_LIBRARY)
Building on Windows
Problem


We really like verbose filenames







GHBowlingYellowBallThrowWith190Degre
eSpinTransitionXMLLoaderTransition.cpp

Our GHEngine project has lots of files
Linker includes all of those filenames in
one shell command
Exceeds maximum line length on
Windows cmd (8191 characters)
Building on Windows
Problem


We really like verbose filenames







Ok, more like
GHGUIPopTransitionXMLLoader.cpp

Our GHEngine project has lots of files
Linker includes all of those filenames in
one shell command
Exceeds maximum line length on
Windows cmd (8191 characters)
Building on Windows
Solution







In Android.mk:
LOCAL_SHORT_COMMANDS := true
Build system generates intermediate list
file and then invokes it with a much
shorter command line
Downside: slower compiles
Can use only in projects that need it.

Contenu connexe

Tendances

Minko - Flash Conference #5
Minko - Flash Conference #5Minko - Flash Conference #5
Minko - Flash Conference #5
Minko3D
 
Lua on Steroids - EclipseCon NA 2012
Lua on Steroids - EclipseCon NA 2012Lua on Steroids - EclipseCon NA 2012
Lua on Steroids - EclipseCon NA 2012
Benjamin Cabé
 
Minko - Targeting Flash/Stage3D with C++ and GLSL
Minko - Targeting Flash/Stage3D with C++ and GLSLMinko - Targeting Flash/Stage3D with C++ and GLSL
Minko - Targeting Flash/Stage3D with C++ and GLSL
Minko3D
 
Fix: static code analysis into our project
Fix: static code analysis into our project Fix: static code analysis into our project
Fix: static code analysis into our project
noelchris3
 
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
영욱 김
 

Tendances (20)

Onivim: Modal Editing from the Future
Onivim: Modal Editing from the FutureOnivim: Modal Editing from the Future
Onivim: Modal Editing from the Future
 
Minko - Flash Conference #5
Minko - Flash Conference #5Minko - Flash Conference #5
Minko - Flash Conference #5
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
GraalVM - MadridJUG 2019-10-22
GraalVM - MadridJUG 2019-10-22GraalVM - MadridJUG 2019-10-22
GraalVM - MadridJUG 2019-10-22
 
Performance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPPerformance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHP
 
Lua on Steroids - EclipseCon NA 2012
Lua on Steroids - EclipseCon NA 2012Lua on Steroids - EclipseCon NA 2012
Lua on Steroids - EclipseCon NA 2012
 
Minko - Targeting Flash/Stage3D with C++ and GLSL
Minko - Targeting Flash/Stage3D with C++ and GLSLMinko - Targeting Flash/Stage3D with C++ and GLSL
Minko - Targeting Flash/Stage3D with C++ and GLSL
 
.NET Core in the Real World
.NET Core in the Real World.NET Core in the Real World
.NET Core in the Real World
 
.NET Core: a new .NET Platform
.NET Core: a new .NET Platform.NET Core: a new .NET Platform
.NET Core: a new .NET Platform
 
.Net Core
.Net Core.Net Core
.Net Core
 
Wasm intro
Wasm introWasm intro
Wasm intro
 
GraalVM - OpenSlava 2019-10-18
GraalVM - OpenSlava 2019-10-18GraalVM - OpenSlava 2019-10-18
GraalVM - OpenSlava 2019-10-18
 
Fix: static code analysis into our project
Fix: static code analysis into our project Fix: static code analysis into our project
Fix: static code analysis into our project
 
Don Wibier
Don WibierDon Wibier
Don Wibier
 
Infrastructure as Data with Ansible
Infrastructure as Data with AnsibleInfrastructure as Data with Ansible
Infrastructure as Data with Ansible
 
Deep Dive Azure Functions - Global Azure Bootcamp 2019
Deep Dive Azure Functions - Global Azure Bootcamp 2019Deep Dive Azure Functions - Global Azure Bootcamp 2019
Deep Dive Azure Functions - Global Azure Bootcamp 2019
 
Short introduction - .net core and .net standard 2.0
Short introduction - .net core and .net standard 2.0Short introduction - .net core and .net standard 2.0
Short introduction - .net core and .net standard 2.0
 
.NET Day Switzerland 2019 - DOCKER + AZURE DEVOPS + KUBERNETES = ♥
.NET Day Switzerland 2019 - DOCKER + AZURE DEVOPS + KUBERNETES = ♥.NET Day Switzerland 2019 - DOCKER + AZURE DEVOPS + KUBERNETES = ♥
.NET Day Switzerland 2019 - DOCKER + AZURE DEVOPS + KUBERNETES = ♥
 
CampJS - Making gaming more fun and efficient
CampJS - Making gaming more fun and efficientCampJS - Making gaming more fun and efficient
CampJS - Making gaming more fun and efficient
 
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
20160409 서브라임텍스트 대신 visual studio code로 만들어 보는 웹 환경
 

En vedette (8)

Kristian Steensen Nielsen
Kristian Steensen NielsenKristian Steensen Nielsen
Kristian Steensen Nielsen
 
Coffee consumption
Coffee consumptionCoffee consumption
Coffee consumption
 
Customer Behavior Bengawan Solo Coffee
Customer Behavior Bengawan Solo CoffeeCustomer Behavior Bengawan Solo Coffee
Customer Behavior Bengawan Solo Coffee
 
Coffee consumption behavior
Coffee consumption behavior Coffee consumption behavior
Coffee consumption behavior
 
Consumer Behavior
Consumer BehaviorConsumer Behavior
Consumer Behavior
 
CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES
CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES
CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES
 
report on consumer preference w.r.t to coffee
report on consumer preference w.r.t to coffeereport on consumer preference w.r.t to coffee
report on consumer preference w.r.t to coffee
 
Market Research on consumer behavior towards coffee bars
Market Research on consumer behavior towards coffee barsMarket Research on consumer behavior towards coffee bars
Market Research on consumer behavior towards coffee bars
 

Similaire à Porting and Maintaining your C++ Game on Android without losing your mind

A Taste of Java ME
A Taste of Java MEA Taste of Java ME
A Taste of Java ME
wiradikusuma
 
Android Development Overview
Android Development OverviewAndroid Development Overview
Android Development Overview
Igor Birman
 
Shape12 6
Shape12 6Shape12 6
Shape12 6
pslulli
 

Similaire à Porting and Maintaining your C++ Game on Android without losing your mind (20)

Mobile Cross-Platform Development in C++
Mobile Cross-Platform Development in C++Mobile Cross-Platform Development in C++
Mobile Cross-Platform Development in C++
 
Android porting for dummies @droidconin 2011
Android porting for dummies @droidconin 2011Android porting for dummies @droidconin 2011
Android porting for dummies @droidconin 2011
 
PPT Companion to Android
PPT Companion to AndroidPPT Companion to Android
PPT Companion to Android
 
PL-4044, OpenACC on AMD APUs and GPUs with the PGI Accelerator Compilers, by ...
PL-4044, OpenACC on AMD APUs and GPUs with the PGI Accelerator Compilers, by ...PL-4044, OpenACC on AMD APUs and GPUs with the PGI Accelerator Compilers, by ...
PL-4044, OpenACC on AMD APUs and GPUs with the PGI Accelerator Compilers, by ...
 
An Introduction To Android
An Introduction To AndroidAn Introduction To Android
An Introduction To Android
 
.Net Debugging Techniques
.Net Debugging Techniques.Net Debugging Techniques
.Net Debugging Techniques
 
.NET Debugging Tips and Techniques
.NET Debugging Tips and Techniques.NET Debugging Tips and Techniques
.NET Debugging Tips and Techniques
 
C# Production Debugging Made Easy
 C# Production Debugging Made Easy C# Production Debugging Made Easy
C# Production Debugging Made Easy
 
Introduction to Android
Introduction to AndroidIntroduction to Android
Introduction to Android
 
A Taste of Java ME
A Taste of Java MEA Taste of Java ME
A Taste of Java ME
 
MSMDC_CLI363
MSMDC_CLI363MSMDC_CLI363
MSMDC_CLI363
 
Android Development Overview
Android Development OverviewAndroid Development Overview
Android Development Overview
 
Designing the Call of Cthulhu app with Google App Engine
Designing the Call of Cthulhu app with Google App EngineDesigning the Call of Cthulhu app with Google App Engine
Designing the Call of Cthulhu app with Google App Engine
 
Thug: a new low-interaction honeyclient
Thug: a new low-interaction honeyclientThug: a new low-interaction honeyclient
Thug: a new low-interaction honeyclient
 
Android basics
Android basicsAndroid basics
Android basics
 
Android tools for testers
Android tools for testersAndroid tools for testers
Android tools for testers
 
Dynamic Slides using OpenOffice.org Impress and Python
Dynamic Slides using OpenOffice.org Impress and PythonDynamic Slides using OpenOffice.org Impress and Python
Dynamic Slides using OpenOffice.org Impress and Python
 
JIT Spraying Never Dies - Bypass CFG By Leveraging WARP Shader JIT Spraying.pdf
JIT Spraying Never Dies - Bypass CFG By Leveraging WARP Shader JIT Spraying.pdfJIT Spraying Never Dies - Bypass CFG By Leveraging WARP Shader JIT Spraying.pdf
JIT Spraying Never Dies - Bypass CFG By Leveraging WARP Shader JIT Spraying.pdf
 
Csharp dot net
Csharp dot netCsharp dot net
Csharp dot net
 
Shape12 6
Shape12 6Shape12 6
Shape12 6
 

Plus de BeMyApp

Présentation des APIs cognitives IBM Watson
Présentation des APIs cognitives IBM WatsonPrésentation des APIs cognitives IBM Watson
Présentation des APIs cognitives IBM Watson
BeMyApp
 

Plus de BeMyApp (20)

Introduction to epid
Introduction to epidIntroduction to epid
Introduction to epid
 
Introduction ciot workshop premeetup
Introduction ciot workshop premeetupIntroduction ciot workshop premeetup
Introduction ciot workshop premeetup
 
Présentation des APIs cognitives IBM Watson
Présentation des APIs cognitives IBM WatsonPrésentation des APIs cognitives IBM Watson
Présentation des APIs cognitives IBM Watson
 
Crédit Agricole S.A. Personae et Parcours
Crédit Agricole S.A. Personae et ParcoursCrédit Agricole S.A. Personae et Parcours
Crédit Agricole S.A. Personae et Parcours
 
Cisco Paris DevNet Hackathon slideshow - Intro
Cisco Paris DevNet Hackathon slideshow - IntroCisco Paris DevNet Hackathon slideshow - Intro
Cisco Paris DevNet Hackathon slideshow - Intro
 
Tumeurs Neuroendocrines : une vue d'ensemble
Tumeurs Neuroendocrines : une vue d'ensembleTumeurs Neuroendocrines : une vue d'ensemble
Tumeurs Neuroendocrines : une vue d'ensemble
 
Building your first game in Unity 3d by Sarah Sexton
Building your first game in Unity 3d  by Sarah SextonBuilding your first game in Unity 3d  by Sarah Sexton
Building your first game in Unity 3d by Sarah Sexton
 
Using intel's real sense to create games with natural user interfaces justi...
Using intel's real sense to create games with natural user interfaces   justi...Using intel's real sense to create games with natural user interfaces   justi...
Using intel's real sense to create games with natural user interfaces justi...
 
Introduction to using the R200 camera & Realsense SDK in Unity3d - Jon Collins
Introduction to using the R200 camera & Realsense SDK in Unity3d - Jon CollinsIntroduction to using the R200 camera & Realsense SDK in Unity3d - Jon Collins
Introduction to using the R200 camera & Realsense SDK in Unity3d - Jon Collins
 
Audio Mixer in Unity5 - Andy Touch
Audio Mixer in Unity5 - Andy TouchAudio Mixer in Unity5 - Andy Touch
Audio Mixer in Unity5 - Andy Touch
 
Shaders - Claudia Doppioslash - Unity With the Best
Shaders - Claudia Doppioslash - Unity With the BestShaders - Claudia Doppioslash - Unity With the Best
Shaders - Claudia Doppioslash - Unity With the Best
 
[HACKATHON CISCO PARIS] Slideshow du workshop Smart City
[HACKATHON CISCO PARIS] Slideshow du workshop Smart City[HACKATHON CISCO PARIS] Slideshow du workshop Smart City
[HACKATHON CISCO PARIS] Slideshow du workshop Smart City
 
Tools to Save Time
Tools to Save TimeTools to Save Time
Tools to Save Time
 
[Workshop e résidents] présentation intent, craft ai, dalkia et incubateur
[Workshop e résidents] présentation intent, craft ai, dalkia et incubateur[Workshop e résidents] présentation intent, craft ai, dalkia et incubateur
[Workshop e résidents] présentation intent, craft ai, dalkia et incubateur
 
[Webinar E-résidents #1] Présentation des différents métiers du bâtiment conn...
[Webinar E-résidents #1] Présentation des différents métiers du bâtiment conn...[Webinar E-résidents #1] Présentation des différents métiers du bâtiment conn...
[Webinar E-résidents #1] Présentation des différents métiers du bâtiment conn...
 
[IoT World Forum Webinar] Review of CMX Cisco technology
[IoT World Forum Webinar] Review of CMX Cisco technology[IoT World Forum Webinar] Review of CMX Cisco technology
[IoT World Forum Webinar] Review of CMX Cisco technology
 
HP Helion Episode 6: Cloud Foundry Summit Recap
HP Helion Episode 6: Cloud Foundry Summit RecapHP Helion Episode 6: Cloud Foundry Summit Recap
HP Helion Episode 6: Cloud Foundry Summit Recap
 
Webinar UI/UX by Francesco Marcellino
Webinar UI/UX by Francesco MarcellinoWebinar UI/UX by Francesco Marcellino
Webinar UI/UX by Francesco Marcellino
 
HP Helion Webinar #5 - Security Beyond Firewalls
HP Helion Webinar #5 - Security Beyond FirewallsHP Helion Webinar #5 - Security Beyond Firewalls
HP Helion Webinar #5 - Security Beyond Firewalls
 
HP Helion Webinar #4 - Open stack the magic pill
HP Helion Webinar #4 - Open stack the magic pillHP Helion Webinar #4 - Open stack the magic pill
HP Helion Webinar #4 - Open stack the magic pill
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Dernier (20)

Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 

Porting and Maintaining your C++ Game on Android without losing your mind

  • 1. Porting and Maintaining Your C++ Game on Android (without losing your mind)
  • 2.
  • 3. Why C++  Cross-Platform support    (Some lesser platforms don’t have a JVM) Don’t want to use Unity, etc Existing C++ Codebase
  • 4. Overview    NDK recap What goes where? C++ vs Java Streamlining packaged app data     Eliminating Data Duplication Compiling multiple architectures Other quirks we’ve run into Some downloads info about our apps
  • 5. NDK Application.mk APP_PROJECT_PATH := $(call my-dir) APP_BUILD_SCRIPT := $(call my-dir)/Android.mk APP_MODULES := GHEngine APP_OPTIM := release APP_STL := stlport_static APP_PLATFORM := android-8
  • 6. NDK (static lib) Android.mk LOCAL_PATH := $(call my-dir) LOCAL_CFLAGS := -Wno-psabi LOCAL_CFLAGS += -D ANDROID LOCAL_MODULE := GHEngine LOCAL_MODULE_FILENAME := libGHEngine LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../Base LOCAL_SRC_FILES += ../../../../Base/GHAppRunner.cpp include $(BUILD_STATIC_LIBRARY)
  • 7. NDK Android.mk (shared lib – loaded by java) LOCAL_MODULE := libGHEngine LOCAL_SRC_FILES := ../../GHEngine/obj/local/armeabi/libGHEngine.a include $(PREBUILT_STATIC_LIBRARY) LOCAL_STATIC_LIBRARIES += libGHEngine include $(BUILD_SHARED_LIBRARY) $(shell cp libs/armeabi/libGHBowling.so ../../../GHBowlingBase/libs/armeabi)
  • 8. NDK JNI Loading the C++ Library public class GHBowlingBaseActivity extends Activity { static { System.loadLibrary("GHBowling"); } }  Loads the file named libGHBowling.so
  • 9. NDK JNI Java (calling C++) public class GHEngineInterface { public native void runNativeFrame(); public native void launchNativeApp(int windowWidth, int windowHeight, String externalStoragePath, int isTablet,int iapIsOn); //resizeWindow, handleTouchStart, handleTouchEnd, handleTouchPos //handleAcceleration, handleJavaPause, handleJavaResume, //handleJavaShutdown,handleBackPressed, calculatePublicKey, //onInterstitialRewardGranted,onRewardInterstitialAvailabilityChange, //onInterstitialDismiss, loadFile,handleTextureLoadConfirmed, //onAdActivation, onAdDeactivation, onIAPPurchase }
  • 10. NDK JNI C++ (called by Java) static jobject globalEngineInterface = 0; extern "C“ __attribute__((visibility("default"))) void Java_goldenhammer_ghbowlingbase_GHEngineInterface_launchNativeApp (JNIEnv* env, jobject engineInterface, jint windowWidth, jint windowHeight, jstring jExternalStoragePath, jint isTablet, jint useIAP) { globalEngineInterface = env->NewGlobalRef(engineInterface); //Engine/Game Initialization goes here. }  When you shut down: env->DeleteGlobalRef(globalEngineInterface);
  • 11. NDK JNI Java (called by C++) public class GHEngineInterface { public void showInterstitialAd() { if (mInterstitialHandler != null) { mInterstitialHandler.showInterstitial(); } else { onInterstitialDismiss(); } } };
  • 12. NDK JNI C++ (calling Java)  GHAndroidInterstitialAd class declaration: JNIEnv& mJNIEnv; jobject mEngineInterface; jmethodID mShowAdMethod;  GHAndroidInterstitialAd ctor: jclass cls = mJNIEnv.GetObjectClass(mEngineInterface); mShowAdMethod = mJNIEnv.GetMethodID(cls, "showInterstitialAd", "()V");  GHAndroidInterstitialAd::activate: mJNIEnv.CallVoidMethod(mJavaObj, mShowAdMethod);
  • 13. What goes Where? C++ or Java  C++    Java    All your platform-independent/pre-existing code Bare minimum wrapper for Android implementation of platform services Typical Android platform code Middleware integration  Can swap middleware vendors of the same service without touching C++ Exceptions:   OpenGL (initialization in Java, most code in C++ or GLSL) File I/O (mix of Java, C++)
  • 14. What Goes Where Java       OpenGL initialization Sound through SoundPool File handle loading through AssetManager Image loading through BitmapFactory Google Play, In-App Billing, etc Ads and other middleware integration   AdMob, AdColony, Chartboost, PlayHaven, Facebook, etc Input Handling  (touches, accelerometer, buttons/gamepad)
  • 15. What Goes Where C++  All your game code   OpenGL rendering code    Ideally 90% of your app Need to handle reinit after lost device fopen using file handle from Java Thin wrapper over JNI calls for everything else
  • 16. What Goes Where Our code distribution.  2800 lines Java   1600 in base project 1200 in master project   Includes middleware integration 50k-150k lines C++   Varies depending on game 6400 Android-specific C++
  • 17. Eliminating Data Duplication Problem    Eclipse wants all data underneath project We want to reuse data (between projects) in our own directory structure We hate maintaining multiple copies of the same data files.
  • 18. Eliminating Data Duplication Solution   Batch file/shell script to copy data On Mac cp ../../../../../data/GHBowling/ballrollloop.wav ../../../GHBowling/assets/ballrollloop.wav cp ../../../../../data/Bowling/GHBowlingAndroid/backwall.jpg ../. ./../GHBowling/assets/backwall.jpg  On Windows copy ..........dataGHBowlingballrollloop.wav ......GHBowlingassetsballrollloop.wav copy ..........dataBowlingGHBowlingAndroidbackwall.jpg ... ...GHBowlingassetsbackwall.jpg
  • 19. Eliminating Data Duplication Batch File Generation  Tool for initial generation  Looks through set of directories with a specified order of preference      Some files are different per-platform We may have Android-specific files We may not, but we prefer iOS-specific to generic Downside: some unnecessary files get copied Maintenance usually done by hand
  • 20. Packaged App Data Problem    Data is packaged through Android build process All files except those with certain excluded file extensions (precompressed file types) are automatically compressed. Platform-agnostic file reading code doesn’t know to uncompress: sees garbage
  • 21. Excluded file extensions  Source: Android Asset Packaging Tool /* these formats are already compressed, or don't compress well */ static const char* kNoCompressExt[] = { ".jpg", ".jpeg", ".png", ".gif", ".wav", ".mp2", ".mp3", ".ogg", ".aac", ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".amr", ".awb", ".wma", ".wmv" };
  • 22. App Data Compression Solution   One option: forgo Eclipse and pass –0 to the AAPT via command line (universally or for certain extensions) What we do cp ../../../../../data/GHBowlingiOS/arrowpixel.glsl ../ ../../GHBowling/assets/arrowpixel.glsl.mp3
  • 23. Compiling for x86 (or other architectures)  In Application.mk: APP_ABI := x86 armeabi  Supported values:      armeabi armeabi-v7a x86 mips all
  • 24. Compiling for x86 Problem  Shared library Android.mk needs to include the correct static library for each architecture   For arm: /armeabi/libGHEngine.a For x86: /x86/libGHEngine.a
  • 25. Compiling for x86 Solution include $(CLEAR_VARS) LOCAL_MODULE := libGHEngine LOCAL_SRC_FILES := ../../GHEngine/obj/local/$(TARGET_ARCH_ABI)/libGHEngine.a include $(PREBUILT_STATIC_LIBRARY)
  • 26. Building on Windows Problem  We really like verbose filenames     GHBowlingYellowBallThrowWith190Degre eSpinTransitionXMLLoaderTransition.cpp Our GHEngine project has lots of files Linker includes all of those filenames in one shell command Exceeds maximum line length on Windows cmd (8191 characters)
  • 27. Building on Windows Problem  We really like verbose filenames     Ok, more like GHGUIPopTransitionXMLLoader.cpp Our GHEngine project has lots of files Linker includes all of those filenames in one shell command Exceeds maximum line length on Windows cmd (8191 characters)
  • 28. Building on Windows Solution     In Android.mk: LOCAL_SHORT_COMMANDS := true Build system generates intermediate list file and then invokes it with a much shorter command line Downside: slower compiles Can use only in projects that need it.