SlideShare a Scribd company logo
Porting and Maintaining Your
C++ Game
on Android
(without losing your mind)
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.

More Related Content

PPTX
C++ on the Web: Run your big 3D game in the browser
PPT
Programming
PPTX
Data Management and Streaming Strategies in Drakensang Online
PPTX
Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5
PDF
Multiplatform C++ on the Web with Emscripten
PDF
Minko - Build WebGL applications with C++ and asm.js
PDF
WebGL games with Minko - Next Game Frontier 2014
PDF
Minko - Creating cross-platform 3D apps with Minko
C++ on the Web: Run your big 3D game in the browser
Programming
Data Management and Streaming Strategies in Drakensang Online
Getting started with Emscripten – Transpiling C / C++ to JavaScript / HTML5
Multiplatform C++ on the Web with Emscripten
Minko - Build WebGL applications with C++ and asm.js
WebGL games with Minko - Next Game Frontier 2014
Minko - Creating cross-platform 3D apps with Minko

What's hot (20)

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

Viewers also liked (8)

PDF
Kristian Steensen Nielsen
DOCX
Coffee consumption
PPTX
Customer Behavior Bengawan Solo Coffee
PPTX
Coffee consumption behavior
PPTX
Consumer Behavior
PPTX
CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES
DOCX
report on consumer preference w.r.t to coffee
PDF
Market Research on consumer behavior towards coffee bars
Kristian Steensen Nielsen
Coffee consumption
Customer Behavior Bengawan Solo Coffee
Coffee consumption behavior
Consumer Behavior
CONSUMER BEHAVIOR TOWARDS COFFEE VENDING MACHINES
report on consumer preference w.r.t to coffee
Market Research on consumer behavior towards coffee bars
Ad

Similar to Porting and Maintaining your C++ Game on Android without losing your mind (20)

PDF
android_project
PPTX
AndEngine
PPTX
Using the android ndk - DroidCon Paris 2014
PDF
NDK Programming in Android
PDF
Using the Android Native Development Kit (NDK)
PPT
Native Android for Windows Developers
PPTX
Advance Android Application Development
PDF
Android is NOT just 'Java on Linux'
PPTX
Android ndk - Introduction
PPT
Porting To Symbian
PPTX
PDF
Introduction to the Android NDK
PDF
An Introduction To Android
PPTX
Android
PPTX
Android Basic
PPTX
PPTX
Android deep dive
PDF
Introduction to the Android NDK
PPT
Webinar on Google Android SDK
android_project
AndEngine
Using the android ndk - DroidCon Paris 2014
NDK Programming in Android
Using the Android Native Development Kit (NDK)
Native Android for Windows Developers
Advance Android Application Development
Android is NOT just 'Java on Linux'
Android ndk - Introduction
Porting To Symbian
Introduction to the Android NDK
An Introduction To Android
Android
Android Basic
Android deep dive
Introduction to the Android NDK
Webinar on Google Android SDK

More from BeMyApp (20)

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

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
August Patch Tuesday
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Tartificialntelligence_presentation.pptx
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
1. Introduction to Computer Programming.pptx
PPTX
A Presentation on Artificial Intelligence
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
TLE Review Electricity (Electricity).pptx
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
Encapsulation_ Review paper, used for researhc scholars
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
August Patch Tuesday
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Tartificialntelligence_presentation.pptx
A comparative analysis of optical character recognition models for extracting...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
A comparative study of natural language inference in Swahili using monolingua...
Digital-Transformation-Roadmap-for-Companies.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
1. Introduction to Computer Programming.pptx
A Presentation on Artificial Intelligence
Diabetes mellitus diagnosis method based random forest with bat algorithm
TLE Review Electricity (Electricity).pptx
SOPHOS-XG Firewall Administrator PPT.pptx

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)
  • 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.