diff --git a/playbook/.cproject b/playbook/.cproject
new file mode 100644
index 0000000000..17e412a641
--- /dev/null
+++ b/playbook/.cproject
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.507133694">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.507133694" moduleId="org.eclipse.cdt.core.settings" name="Device-Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.507133694" name="Device-Debug" parent="com.qnx.qcc.configuration.exe.debug">
+					<folderInfo id="com.qnx.qcc.configuration.exe.debug.507133694." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.debug.2065020807" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.2049874529" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1371677239" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Device-Debug}" id="com.qnx.nto.51011824" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.312527984" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1343943391" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.1008704037" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.1389175009" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.209097800" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1775248205" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL20"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.827203004" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.722220103" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.2023833959" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.326906113" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.2091187444" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.1757561643" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.825393804" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.676562861" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.187715937" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.992939518" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.815783219" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.release.237026123">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.release.237026123" moduleId="org.eclipse.cdt.core.settings" name="Device-Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.release.237026123" name="Device-Release" parent="com.qnx.qcc.configuration.exe.release">
+					<folderInfo id="com.qnx.qcc.configuration.exe.release.237026123." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.release.1766368467" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.1345690239" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1497663639" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Device-Release}" id="com.qnx.nto.379146748" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.521537247" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1293497463" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.1333983864" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.421937377" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.426935293" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL20"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.pie.145409477" name="Position Independent Executable (-fPIE)" superClass="com.qnx.qcc.option.compiler.pie" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1285267130" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-frecord-gcc-switches"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.472778173" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.676105057" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<inputType id="com.qnx.qcc.inputType.assembler.585345918" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.939866545" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.libraries.1258752690" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1833953103" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.pie.812020863" name="Position Independent Executable (-pie)" superClass="com.qnx.qcc.option.linker.pie" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.security.1849150952" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.1440676413" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.1239899316" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.profile.491517832">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.profile.491517832" moduleId="org.eclipse.cdt.core.settings" name="Device-Profile">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="Build for Profiling" id="com.qnx.qcc.configuration.exe.profile.491517832" name="Device-Profile" parent="com.qnx.qcc.configuration.exe.profile">
+					<folderInfo id="com.qnx.qcc.configuration.exe.profile.491517832." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.profile.1940927190" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.810106304" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1744556277" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Device-Profile}" id="com.qnx.nto.220354791" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.578454843" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1421628131" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.995395785" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.profile2.1637519834" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.1145263849" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.1305803908" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.213513124" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL20"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.1632181586" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.820786892" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.1981772840" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.1036437237" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1612406011" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.1674789686" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.profile2.317116750" name="Build for Profiling (Function Instrumentation) (-lprofiling)" superClass="com.qnx.qcc.option.linker.profile2" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.2133360025" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1367143286" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.1679805773" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.292607681" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.1845279644" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.profile.coverage.511003583">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.profile.coverage.511003583" moduleId="org.eclipse.cdt.core.settings" name="Device-Coverage">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="Build for Code Coverage" id="com.qnx.qcc.configuration.exe.profile.coverage.511003583" name="Device-Coverage" parent="com.qnx.qcc.configuration.exe.profile.coverage">
+					<folderInfo id="com.qnx.qcc.configuration.exe.profile.coverage.511003583." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.coverage.290877093" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.775910002" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.264464274" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Device-Coverage}" id="com.qnx.nto.1360968012" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.1699204352" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.692343476" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.1061058825" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.coverage.457849293" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.2069434559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.521807592" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1725725626" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL11"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.1469526261" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.1771923802" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.1595223019" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.2129805542" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1942866882" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.790242117" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.coverage.73478781" name="Build for Code Coverage (-ftest-coverage -fprofile-arcs -p)" superClass="com.qnx.qcc.option.linker.coverage" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.1198094350" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv1_CM"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.496032417" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.1745797008" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.284013832" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.284978789" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.1423528231">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.1423528231" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.1423528231" name="Simulator-Debug" parent="com.qnx.qcc.configuration.exe.debug">
+					<folderInfo id="com.qnx.qcc.configuration.exe.debug.1423528231." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.debug.76634438" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.2126292613" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Simulator-Debug}" id="com.qnx.nto.1609605066" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.1279842281" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.685085389" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.1031247323" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.414786601" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.157472670" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1166581028" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL11"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.479331921" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.418457356" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.2104087013" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.1407803369" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.347466214" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.60846036" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.456416978" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv1_CM"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1381715984" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.1319793451" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.1580301577" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.33373882" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.profile.1740368212">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.profile.1740368212" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Profile">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="Build for Profiling" id="com.qnx.qcc.configuration.exe.profile.1740368212" name="Simulator-Profile" parent="com.qnx.qcc.configuration.exe.profile">
+					<folderInfo id="com.qnx.qcc.configuration.exe.profile.1740368212." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.profile.644425262" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1501332643" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Simulator-Profile}" id="com.qnx.nto.1697233247" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.2084544149" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1872714412" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.1567415109" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.profile2.762240993" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.946910608" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.817746405" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.431450507" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL11"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.1830961908" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.1153258106" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.89625770" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.113638613" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1483351797" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.1293285876" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.profile2.234673702" name="Build for Profiling (Function Instrumentation) (-lprofiling)" superClass="com.qnx.qcc.option.linker.profile2" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.1482926481" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv1_CM"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1397065257" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.203141846" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.1574710195" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.1366694225" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.profile.coverage.1511241566">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.profile.coverage.1511241566" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Coverage">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="Build for Code Coverage" id="com.qnx.qcc.configuration.exe.profile.coverage.1511241566" name="Simulator-Coverage" parent="com.qnx.qcc.configuration.exe.profile.coverage">
+					<folderInfo id="com.qnx.qcc.configuration.exe.profile.coverage.1511241566." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.coverage.1041575864" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.687107132" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/CubeRotate/Simulator-Coverage}" id="com.qnx.nto.622179974" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/>
+							<tool id="com.qnx.qcc.tool.compiler.1804299414" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1547874153" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compile.debug.506984407" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.coverage.940712331" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.includePath.146866900" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.security.733048683" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.252268326" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="USING_GL11"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.1800311584" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.1877634243" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.166061824" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.assembler.2029110252" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.551801963" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.1904146116" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.coverage.1717304216" name="Build for Code Coverage (-ftest-coverage -fprofile-arcs -p)" superClass="com.qnx.qcc.option.linker.coverage" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraries.1222510627" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="GLESv1_CM"/>
+									<listOptionValue builtIn="false" value="freetype"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="m"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1867628370" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.security.1635799651" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<inputType id="com.qnx.qcc.inputType.linker.1740916343" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.589338426" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="CubeRotate.null.476443474" name="CubeRotate"/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+	<storageModule moduleId="refreshScope" versionNumber="1">
+		<resource resourceType="PROJECT" workspacePath="/RetroArch"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.491517832">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.1423528231">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.1740368212">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.507133694">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.1511241566">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.511003583">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.release.237026123">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+</cproject>
diff --git a/playbook/.project b/playbook/.project
new file mode 100644
index 0000000000..656b50ab7e
--- /dev/null
+++ b/playbook/.project
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>RetroArch</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>make</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildLocation</key>
+					<value>${workspace_loc:/CubeRotate/Device-Debug}</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>true</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+		<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
+	</natures>
+</projectDescription>
diff --git a/playbook/.settings/org.eclipse.cdt.codan.core.prefs b/playbook/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000000..59043abc64
--- /dev/null
+++ b/playbook/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,66 @@
+#Sun Feb 24 21:20:16 CET 2013
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={no_break_comment\=>"no break",last_case_param\=>true,empty_case_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
diff --git a/playbook/bar-descriptor.xml b/playbook/bar-descriptor.xml
new file mode 100644
index 0000000000..d6e439dbcb
--- /dev/null
+++ b/playbook/bar-descriptor.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
+
+<!-- BlackBerry Tablet OS application descriptor file.
+
+    Specifies parameters for identifying, installing, and launching native applications on BlackBerry Tablet OS.
+
+-->
+
+    <!-- A universally unique application identifier. Must be unique across all BlackBerry Tablet OS applications.
+         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
+    <id>com.RetroArch</id>
+
+    <!-- The name that is displayed in the BlackBerry Tablet OS application installer. 
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <name>RetroArch</name>
+    
+    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
+         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
+         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
+    <versionNumber>1.0.0</versionNumber>
+
+    <!-- Fourth digit segment of the package version. First three segments are taken from the 
+         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
+    <buildId>1</buildId>
+                 
+    <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. -->
+    <!-- <versionLabel></versionLabel> -->
+
+    <!-- Description, displayed in the BlackBerry Tablet OS application installer.
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <description>Multi-emulator/multi-game system application</description>
+
+    <!-- Copyright information. Optional. -->
+    <!-- <copyright></copyright> -->
+
+    <!--  Name of author which is used for signing. Must match the developer name of your development certificate. -->
+    <author>Example Inc.</author>
+    
+    <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
+    <!-- <authorId>ABC1234YjsnUk235h</authorId> -->
+   
+    <initialWindow>
+        <systemChrome>none</systemChrome>
+        <transparent>false</transparent>
+    </initialWindow>
+    
+    <!--  The category where the application appears. Either core.games or core.media. -->
+    <category>core.games</category>
+    <asset path="icon.png">icon.png</asset>
+    <!-- <asset path="LICENSE">LICENSE</asset> -->
+    <!-- <asset path="NOTICE">NOTICE</asset> -->
+    <configuration id="com.qnx.qcc.configuration.exe.debug.507133694" name="Device-Debug">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Debug/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.release.237026123" name="Device-Release">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Release/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.profile.491517832" name="Device-Profile">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Profile/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.profile.coverage.511003583" name="Device-Coverage">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Coverage/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.debug.1423528231" name="Simulator-Debug">
+       <platformArchitecture>x86</platformArchitecture>
+       <asset path="Simulator-Debug/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.profile.1740368212" name="Simulator-Profile">
+       <platformArchitecture>x86</platformArchitecture>
+       <asset path="Simulator-Profile/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    <configuration id="com.qnx.qcc.configuration.exe.profile.coverage.1511241566" name="Simulator-Coverage">
+       <platformArchitecture>x86</platformArchitecture>
+       <asset path="Simulator-Coverage/RetroArch" entry="true" type="Qnx/Elf">RetroArch</asset>
+    </configuration>
+    
+    <!--  The icon for the application, which should be 86x86. -->
+    <icon>
+        <image>icon.png</image>
+    </icon>
+    
+    <!--  The splash screen that will appear when your application is launching. Should be 1024x600. -->
+    <!-- <splashscreen></splashscreen> -->
+
+    <!-- Request permission to execute native code.  Required for native applications. -->
+    <action system="true">run_native</action>
+    
+    <!--  The permissions requested by your application. -->
+    <!--  <action>access_shared</action> -->
+    <!--  <action>record_audio</action> -->
+    <!--  <action>read_geolocation</action> -->
+    <!--  <action>use_camera</action> -->
+    <!--  <action>access_internet</action> -->
+    <!--  <action>play_audio</action> -->
+    <!--  <action>post_notification</action> -->
+    <!--  <action>set_audio_volume</action> -->
+    <!--  <action>read_device_identifying_information</action> -->
+
+    <!-- Ensure that shared libraries in the package are found at run-time. -->
+    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
+    
+</qnx>
diff --git a/playbook/icon.png b/playbook/icon.png
new file mode 100644
index 0000000000..a113106a99
Binary files /dev/null and b/playbook/icon.png differ
diff --git a/playbook/src/bbutil.c b/playbook/src/bbutil.c
new file mode 100644
index 0000000000..0e56eab62b
--- /dev/null
+++ b/playbook/src/bbutil.c
@@ -0,0 +1,1051 @@
+/*
+ * Copyright (c) 2011-2012 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/keycodes.h>
+#include <time.h>
+#include <stdbool.h>
+#include <math.h>
+
+#include "bbutil.h"
+
+#ifdef USING_GL11
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#elif defined(USING_GL20)
+#include <GLES2/gl2.h>
+#else
+#error bbutil must be compiled with either USING_GL11 or USING_GL20 flags
+#endif
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include "png.h"
+
+EGLDisplay egl_disp;
+EGLSurface egl_surf;
+
+static EGLConfig egl_conf;
+static EGLContext egl_ctx;
+
+static screen_context_t screen_ctx;
+static screen_window_t screen_win;
+static screen_display_t screen_disp;
+static int nbuffers = 2;
+static int initialized = 0;
+
+#ifdef USING_GL20
+static GLuint text_rendering_program;
+static int text_program_initialized = 0;
+static GLint positionLoc;
+static GLint texcoordLoc;
+static GLint textureLoc;
+static GLint colorLoc;
+#endif
+
+struct font_t {
+    unsigned int font_texture;
+    float pt;
+    float advance[128];
+    float width[128];
+    float height[128];
+    float tex_x1[128];
+    float tex_x2[128];
+    float tex_y1[128];
+    float tex_y2[128];
+    float offset_x[128];
+    float offset_y[128];
+    int initialized;
+};
+
+
+static void
+bbutil_egl_perror(const char *msg) {
+    static const char *errmsg[] = {
+        "function succeeded",
+        "EGL is not initialized, or could not be initialized, for the specified display",
+        "cannot access a requested resource",
+        "failed to allocate resources for the requested operation",
+        "an unrecognized attribute or attribute value was passed in an attribute list",
+        "an EGLConfig argument does not name a valid EGLConfig",
+        "an EGLContext argument does not name a valid EGLContext",
+        "the current surface of the calling thread is no longer valid",
+        "an EGLDisplay argument does not name a valid EGLDisplay",
+        "arguments are inconsistent",
+        "an EGLNativePixmapType argument does not refer to a valid native pixmap",
+        "an EGLNativeWindowType argument does not refer to a valid native window",
+        "one or more argument values are invalid",
+        "an EGLSurface argument does not name a valid surface configured for rendering",
+        "a power management event has occurred",
+        "unknown error code"
+    };
+
+    int message_index = eglGetError() - EGL_SUCCESS;
+
+    if (message_index < 0 || message_index > 14)
+        message_index = 15;
+
+    fprintf(stderr, "%s: %s\n", msg, errmsg[message_index]);
+}
+
+int
+bbutil_init_egl(screen_context_t ctx) {
+    int usage;
+    int format = SCREEN_FORMAT_RGBX8888;
+    EGLint interval = 1;
+    int rc, num_configs;
+
+    EGLint attrib_list[]= { EGL_RED_SIZE,        8,
+                            EGL_GREEN_SIZE,      8,
+                            EGL_BLUE_SIZE,       8,
+                            EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+                            EGL_RENDERABLE_TYPE, 0,
+                            EGL_NONE};
+
+#ifdef USING_GL11
+    usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION;
+    attrib_list[9] = EGL_OPENGL_ES_BIT;
+#elif defined(USING_GL20)
+    usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;
+    attrib_list[9] = EGL_OPENGL_ES2_BIT;
+    EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+#else
+    fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n");
+    return EXIT_FAILURE;
+#endif
+
+    //Simple egl initialization
+    screen_ctx = ctx;
+
+    egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (egl_disp == EGL_NO_DISPLAY) {
+        bbutil_egl_perror("eglGetDisplay");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = eglInitialize(egl_disp, NULL, NULL);
+    if (rc != EGL_TRUE) {
+        bbutil_egl_perror("eglInitialize");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = eglBindAPI(EGL_OPENGL_ES_API);
+
+    if (rc != EGL_TRUE) {
+        bbutil_egl_perror("eglBindApi");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    if(!eglChooseConfig(egl_disp, attrib_list, &egl_conf, 1, &num_configs)) {
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+#ifdef USING_GL20
+        egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes);
+#elif defined(USING_GL11)
+        egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL);
+#endif
+
+    if (egl_ctx == EGL_NO_CONTEXT) {
+        bbutil_egl_perror("eglCreateContext");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_create_window(&screen_win, screen_ctx);
+    if (rc) {
+        perror("screen_create_window");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format);
+    if (rc) {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
+    if (rc) {
+        perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp);
+    if (rc) {
+        perror("screen_get_window_property_pv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    int screen_resolution[2];
+
+    rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution);
+    if (rc) {
+        perror("screen_get_display_property_iv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    int angle = atoi(getenv("ORIENTATION"));
+
+    screen_display_mode_t screen_mode;
+    rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
+    if (rc) {
+        perror("screen_get_display_property_pv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    int size[2];
+    rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
+    if (rc) {
+        perror("screen_get_window_property_iv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    int buffer_size[2] = {size[0], size[1]};
+
+    if ((angle == 0) || (angle == 180)) {
+        if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
+            ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) {
+                buffer_size[1] = size[0];
+                buffer_size[0] = size[1];
+        }
+    } else if ((angle == 90) || (angle == 270)){
+        if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
+            ((screen_mode.width < screen_mode.height && size[0] < size[1]))) {
+                buffer_size[1] = size[0];
+                buffer_size[0] = size[1];
+        }
+    } else {
+         fprintf(stderr, "Navigator returned an unexpected orientation angle.\n");
+         bbutil_terminate();
+         return EXIT_FAILURE;
+    }
+
+    rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size);
+    if (rc) {
+        perror("screen_set_window_property_iv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
+    if (rc) {
+        perror("screen_set_window_property_iv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_create_window_buffers(screen_win, nbuffers);
+    if (rc) {
+        perror("screen_create_window_buffers");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
+    if (egl_surf == EGL_NO_SURFACE) {
+        bbutil_egl_perror("eglCreateWindowSurface");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
+    if (rc != EGL_TRUE) {
+        bbutil_egl_perror("eglMakeCurrent");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    rc = eglSwapInterval(egl_disp, interval);
+    if (rc != EGL_TRUE) {
+        bbutil_egl_perror("eglSwapInterval");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    initialized = 1;
+
+    return EXIT_SUCCESS;
+}
+
+void
+bbutil_terminate() {
+    //Typical EGL cleanup
+    if (egl_disp != EGL_NO_DISPLAY) {
+        eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        if (egl_surf != EGL_NO_SURFACE) {
+            eglDestroySurface(egl_disp, egl_surf);
+            egl_surf = EGL_NO_SURFACE;
+        }
+        if (egl_ctx != EGL_NO_CONTEXT) {
+            eglDestroyContext(egl_disp, egl_ctx);
+            egl_ctx = EGL_NO_CONTEXT;
+        }
+        if (screen_win != NULL) {
+            screen_destroy_window(screen_win);
+            screen_win = NULL;
+        }
+        eglTerminate(egl_disp);
+        egl_disp = EGL_NO_DISPLAY;
+    }
+    eglReleaseThread();
+
+    initialized = 0;
+}
+
+void
+bbutil_swap() {
+    int rc = eglSwapBuffers(egl_disp, egl_surf);
+    if (rc != EGL_TRUE) {
+        bbutil_egl_perror("eglSwapBuffers");
+    }
+}
+
+/* Finds the next power of 2 */
+static inline int
+nextp2(int x)
+{
+    int val = 1;
+    while(val < x) val <<= 1;
+    return val;
+}
+
+font_t* bbutil_load_font(const char* path, int point_size, int dpi) {
+    FT_Library library;
+    FT_Face face;
+    int c;
+    int i, j;
+    font_t* font;
+
+    if (!initialized) {
+        fprintf(stderr, "EGL has not been initialized\n");
+        return NULL;
+    }
+
+    if (!path){
+        fprintf(stderr, "Invalid path to font file\n");
+        return NULL;
+    }
+
+    if(FT_Init_FreeType(&library)) {
+        fprintf(stderr, "Error loading Freetype library\n");
+        return NULL;
+    }
+    if (FT_New_Face(library, path,0,&face)) {
+        fprintf(stderr, "Error loading font %s\n", path);
+        return NULL;
+    }
+
+    if(FT_Set_Char_Size ( face, point_size * 64, point_size * 64, dpi, dpi)) {
+        fprintf(stderr, "Error initializing character parameters\n");
+        return NULL;
+    }
+
+    font = (font_t*) malloc(sizeof(font_t));
+
+    if (!font) {
+        fprintf(stderr, "Unable to allocate memory for font structure\n");
+        return NULL;
+    }
+
+    font->initialized = 0;
+    font->pt = point_size;
+
+    glGenTextures(1, &(font->font_texture));
+
+    //Let each glyph reside in 32x32 section of the font texture
+    int segment_size_x = 0, segment_size_y = 0;
+    int num_segments_x = 16;
+    int num_segments_y = 8;
+
+    FT_GlyphSlot slot;
+    FT_Bitmap bmp;
+    int glyph_width, glyph_height;
+
+    //First calculate the max width and height of a character in a passed font
+    for(c = 0; c < 128; c++) {
+        if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
+            fprintf(stderr, "FT_Load_Char failed\n");
+            free(font);
+            return NULL;
+        }
+
+        slot = face->glyph;
+        bmp = slot->bitmap;
+
+        glyph_width = bmp.width;
+        glyph_height = bmp.rows;
+
+        if (glyph_width > segment_size_x) {
+            segment_size_x = glyph_width;
+        }
+
+        if (glyph_height > segment_size_y) {
+            segment_size_y = glyph_height;
+        }
+    }
+
+    int font_tex_width = nextp2(num_segments_x * segment_size_x);
+    int font_tex_height = nextp2(num_segments_y * segment_size_y);
+
+    int bitmap_offset_x = 0, bitmap_offset_y = 0;
+
+    GLubyte* font_texture_data = (GLubyte*) calloc(2 * font_tex_width * font_tex_height, sizeof(GLubyte));
+
+    if (!font_texture_data) {
+        fprintf(stderr, "Failed to allocate memory for font texture\n");
+        free(font);
+        return NULL;
+    }
+
+    // Fill font texture bitmap with individual bmp data and record appropriate size, texture coordinates and offsets for every glyph
+    for(c = 0; c < 128; c++) {
+        if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
+            fprintf(stderr, "FT_Load_Char failed\n");
+            free(font);
+            return NULL;
+        }
+
+        slot = face->glyph;
+        bmp = slot->bitmap;
+
+        glyph_width = bmp.width;
+        glyph_height = bmp.rows;
+
+        div_t temp = div(c, num_segments_x);
+
+        bitmap_offset_x = segment_size_x * temp.rem;
+        bitmap_offset_y = segment_size_y * temp.quot;
+
+        for (j = 0; j < glyph_height; j++) {
+            for (i = 0; i < glyph_width; i++) {
+                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 0] =
+                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 1] =
+                    (i >= bmp.width || j >= bmp.rows)? 0 : bmp.buffer[i + bmp.width * j];
+            }
+        }
+
+        font->advance[c] = (float)(slot->advance.x >> 6);
+        font->tex_x1[c] = (float)bitmap_offset_x / (float) font_tex_width;
+        font->tex_x2[c] = (float)(bitmap_offset_x + bmp.width) / (float)font_tex_width;
+        font->tex_y1[c] = (float)bitmap_offset_y / (float) font_tex_height;
+        font->tex_y2[c] = (float)(bitmap_offset_y + bmp.rows) / (float)font_tex_height;
+        font->width[c] = bmp.width;
+        font->height[c] = bmp.rows;
+        font->offset_x[c] = (float)slot->bitmap_left;
+        font->offset_y[c] =  (float)((slot->metrics.horiBearingY-face->glyph->metrics.height) >> 6);
+    }
+
+    glBindTexture(GL_TEXTURE_2D, font->font_texture);
+    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, font_tex_width, font_tex_height, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, font_texture_data);
+
+    free(font_texture_data);
+
+    FT_Done_Face(face);
+    FT_Done_FreeType(library);
+
+    font->initialized = 1;
+    return font;
+}
+
+void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r, float g, float b, float a) {
+    int i, c;
+    GLfloat *vertices;
+    GLfloat *texture_coords;
+    GLshort* indices;
+
+    float pen_x = 0.0f;
+
+    if (!font) {
+        fprintf(stderr, "Font must not be null\n");
+        return;
+    }
+
+    if (!font->initialized) {
+        fprintf(stderr, "Font has not been loaded\n");
+        return;
+    }
+
+    if (!msg) {
+        return;
+    }
+
+    const int msg_len = strlen(msg);
+
+    vertices = (GLfloat*) malloc(sizeof(GLfloat) * 8 * msg_len);
+    texture_coords = (GLfloat*) malloc(sizeof(GLfloat) * 8 * msg_len);
+
+    indices = (GLshort*) malloc(sizeof(GLfloat) * 6 * msg_len);
+
+    for(i = 0; i < msg_len; ++i) {
+        c = msg[i];
+
+        vertices[8 * i + 0] = x + pen_x + font->offset_x[c];
+        vertices[8 * i + 1] = y + font->offset_y[c];
+        vertices[8 * i + 2] = vertices[8 * i + 0] + font->width[c];
+        vertices[8 * i + 3] = vertices[8 * i + 1];
+        vertices[8 * i + 4] = vertices[8 * i + 0];
+        vertices[8 * i + 5] = vertices[8 * i + 1] + font->height[c];
+        vertices[8 * i + 6] = vertices[8 * i + 2];
+        vertices[8 * i + 7] = vertices[8 * i + 5];
+
+        texture_coords[8 * i + 0] = font->tex_x1[c];
+        texture_coords[8 * i + 1] = font->tex_y2[c];
+        texture_coords[8 * i + 2] = font->tex_x2[c];
+        texture_coords[8 * i + 3] = font->tex_y2[c];
+        texture_coords[8 * i + 4] = font->tex_x1[c];
+        texture_coords[8 * i + 5] = font->tex_y1[c];
+        texture_coords[8 * i + 6] = font->tex_x2[c];
+        texture_coords[8 * i + 7] = font->tex_y1[c];
+
+        indices[i * 6 + 0] = 4 * i + 0;
+        indices[i * 6 + 1] = 4 * i + 1;
+        indices[i * 6 + 2] = 4 * i + 2;
+        indices[i * 6 + 3] = 4 * i + 2;
+        indices[i * 6 + 4] = 4 * i + 1;
+        indices[i * 6 + 5] = 4 * i + 3;
+
+        //Assume we are only working with typewriter fonts
+        pen_x += font->advance[c];
+    }
+#ifdef USING_GL11
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_BLEND);
+
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    glColor4f(r, g, b, a);
+
+    glVertexPointer(2, GL_FLOAT, 0, vertices);
+    glTexCoordPointer(2, GL_FLOAT, 0, texture_coords);
+    glBindTexture(GL_TEXTURE_2D, font->font_texture);
+
+    glDrawElements(GL_TRIANGLES, 6 * msg_len, GL_UNSIGNED_SHORT, indices);
+
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+#elif defined USING_GL20
+    if (!text_program_initialized) {
+        GLint status;
+
+        // Create shaders if this hasn't been done already
+        const char* v_source =
+                "precision mediump float;"
+                "attribute vec2 a_position;"
+                "attribute vec2 a_texcoord;"
+                "varying vec2 v_texcoord;"
+                "void main()"
+                "{"
+                "   gl_Position = vec4(a_position, 0.0, 1.0);"
+                "    v_texcoord = a_texcoord;"
+                "}";
+
+        const char* f_source =
+                "precision lowp float;"
+                "varying vec2 v_texcoord;"
+                "uniform sampler2D u_font_texture;"
+                "uniform vec4 u_col;"
+                "void main()"
+                "{"
+                "    vec4 temp = texture2D(u_font_texture, v_texcoord);"
+                "    gl_FragColor = u_col * temp;"
+                "}";
+
+        // Compile the vertex shader
+        GLuint vs = glCreateShader(GL_VERTEX_SHADER);
+
+        if (!vs) {
+            fprintf(stderr, "Failed to create vertex shader: %d\n", glGetError());
+            return;
+        } else {
+            glShaderSource(vs, 1, &v_source, 0);
+            glCompileShader(vs);
+            glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
+            if (GL_FALSE == status) {
+                GLchar log[256];
+                glGetShaderInfoLog(vs, 256, NULL, log);
+
+                fprintf(stderr, "Failed to compile vertex shader: %s\n", log);
+
+                glDeleteShader(vs);
+            }
+        }
+
+        // Compile the fragment shader
+        GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
+
+        if (!fs) {
+            fprintf(stderr, "Failed to create fragment shader: %d\n", glGetError());
+            return;
+        } else {
+            glShaderSource(fs, 1, &f_source, 0);
+            glCompileShader(fs);
+            glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
+            if (GL_FALSE == status) {
+                GLchar log[256];
+                glGetShaderInfoLog(fs, 256, NULL, log);
+
+                fprintf(stderr, "Failed to compile fragment shader: %s\n", log);
+
+                glDeleteShader(vs);
+                glDeleteShader(fs);
+
+                return;
+            }
+        }
+
+        // Create and link the program
+        text_rendering_program = glCreateProgram();
+        if (text_rendering_program)
+        {
+            glAttachShader(text_rendering_program, vs);
+            glAttachShader(text_rendering_program, fs);
+            glLinkProgram(text_rendering_program);
+
+            glGetProgramiv(text_rendering_program, GL_LINK_STATUS, &status);
+            if (status == GL_FALSE)    {
+                GLchar log[256];
+                glGetProgramInfoLog(fs, 256, NULL, log);
+
+                fprintf(stderr, "Failed to link text rendering shader program: %s\n", log);
+
+                glDeleteProgram(text_rendering_program);
+                text_rendering_program = 0;
+
+                return;
+            }
+        } else {
+            fprintf(stderr, "Failed to create a shader program\n");
+
+            glDeleteShader(vs);
+            glDeleteShader(fs);
+            return;
+        }
+
+        // We don't need the shaders anymore - the program is enough
+        glDeleteShader(fs);
+        glDeleteShader(vs);
+
+        glUseProgram(text_rendering_program);
+
+        // Store the locations of the shader variables we need later
+        positionLoc = glGetAttribLocation(text_rendering_program, "a_position");
+        texcoordLoc = glGetAttribLocation(text_rendering_program, "a_texcoord");
+        textureLoc = glGetUniformLocation(text_rendering_program, "u_font_texture");
+        colorLoc = glGetUniformLocation(text_rendering_program, "u_col");
+
+        text_program_initialized = 1;
+    }
+
+    glEnable(GL_BLEND);
+
+    //Map text coordinates from (0...surface width, 0...surface height) to (-1...1, -1...1)
+    //this make our vertex shader very simple and also works irrespective of orientation changes
+    EGLint surface_width, surface_height;
+
+    eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
+    eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
+
+    for(i = 0; i < 4 * msg_len; ++i) {
+        vertices[2 * i + 0] = 2 * vertices[2 * i + 0] / surface_width - 1.0f;
+        vertices[2 * i + 1] = 2 * vertices[2 * i + 1] / surface_height - 1.0f;
+    }
+
+    //Render text
+    glUseProgram(text_rendering_program);
+
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, font->font_texture);
+    glUniform1i(textureLoc, 0);
+
+    glUniform4f(colorLoc, r, g, b, a);
+
+    glEnableVertexAttribArray(positionLoc);
+    glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+
+    glEnableVertexAttribArray(texcoordLoc);
+    glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, texture_coords);
+
+       //Draw the string
+    glDrawElements(GL_TRIANGLES, 6 * msg_len, GL_UNSIGNED_SHORT, indices);
+
+    glDisableVertexAttribArray(positionLoc);
+    glDisableVertexAttribArray(texcoordLoc);
+#else
+    fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n");
+#endif
+
+    free(vertices);
+    free(texture_coords);
+    free(indices);
+}
+
+void bbutil_destroy_font(font_t* font) {
+    if (!font) {
+        return;
+    }
+
+    glDeleteTextures(1, &(font->font_texture));
+
+    free(font);
+}
+
+void bbutil_measure_text(font_t* font, const char* msg, float* width, float* height) {
+    int i, c;
+
+    if (!msg) {
+        return;
+    }
+
+    const int msg_len  =strlen(msg);
+
+    if (width) {
+        //Width of a text rectangle is a sum advances for every glyph in a string
+        *width = 0.0f;
+
+        for(i = 0; i < msg_len; ++i) {
+            c = msg[i];
+            *width += font->advance[c];
+        }
+    }
+
+    if (height) {
+        //Height of a text rectangle is a high of a tallest glyph in a string
+        *height = 0.0f;
+
+        for(i = 0; i < msg_len; ++i) {
+            c = msg[i];
+
+            if (*height < font->height[c]) {
+                *height = font->height[c];
+            }
+        }
+    }
+}
+
+int bbutil_load_texture(const char* filename, int* width, int* height, float* tex_x, float* tex_y, unsigned int *tex) {
+    int i;
+    GLuint format;
+    //header for testing if it is a png
+    png_byte header[8];
+
+    if (!tex) {
+        return EXIT_FAILURE;
+    }
+
+    //open file as binary
+    FILE *fp = fopen(filename, "rb");
+    if (!fp) {
+        return EXIT_FAILURE;
+    }
+
+    //read the header
+    fread(header, 1, 8, fp);
+
+    //test if png
+    int is_png = !png_sig_cmp(header, 0, 8);
+    if (!is_png) {
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //create png struct
+    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr) {
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //create png info struct
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr) {
+        png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //create png info struct
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info) {
+        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //setup error handling (required without using custom error handlers above)
+    if (setjmp(png_jmpbuf(png_ptr))) {
+        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //init png reading
+    png_init_io(png_ptr, fp);
+
+    //let libpng know you already read the first 8 bytes
+    png_set_sig_bytes(png_ptr, 8);
+
+    // read all the info up to the image data
+    png_read_info(png_ptr, info_ptr);
+
+    //variables to pass to get info
+    int bit_depth, color_type;
+    png_uint_32 image_width, image_height;
+
+    // get info about png
+    png_get_IHDR(png_ptr, info_ptr, &image_width, &image_height, &bit_depth, &color_type, NULL, NULL, NULL);
+
+    switch (color_type)
+    {
+        case PNG_COLOR_TYPE_RGBA:
+            format = GL_RGBA;
+            break;
+        case PNG_COLOR_TYPE_RGB:
+            format = GL_RGB;
+            break;
+        default:
+            fprintf(stderr,"Unsupported PNG color type (%d) for texture: %s", (int)color_type, filename);
+            fclose(fp);
+            png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+            return NULL;
+    }
+
+    // Update the png info struct.
+    png_read_update_info(png_ptr, info_ptr);
+
+    // Row size in bytes.
+    int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+
+    // Allocate the image_data as a big block, to be given to opengl
+    png_byte *image_data = (png_byte*) malloc(sizeof(png_byte) * rowbytes * image_height);
+
+    if (!image_data) {
+        //clean up memory and close stuff
+        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    //row_pointers is for pointing to image_data for reading the png with libpng
+    png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * image_height);
+    if (!row_pointers) {
+        //clean up memory and close stuff
+        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+        free(image_data);
+        fclose(fp);
+        return EXIT_FAILURE;
+    }
+
+    // set the individual row_pointers to point at the correct offsets of image_data
+    for (i = 0; i < image_height; i++) {
+        row_pointers[image_height - 1 - i] = image_data + i * rowbytes;
+    }
+
+    //read the png into image_data through row_pointers
+    png_read_image(png_ptr, row_pointers);
+
+    int tex_width, tex_height;
+
+    tex_width = nextp2(image_width);
+    tex_height = nextp2(image_height);
+
+    glGenTextures(1, tex);
+    glBindTexture(GL_TEXTURE_2D, (*tex));
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    if ((tex_width != image_width) || (tex_height != image_height) ) {
+        glTexImage2D(GL_TEXTURE_2D, 0, format, tex_width, tex_height, 0, format, GL_UNSIGNED_BYTE, NULL);
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, format, GL_UNSIGNED_BYTE, image_data);
+    } else {
+        glTexImage2D(GL_TEXTURE_2D, 0, format, tex_width, tex_height, 0, format, GL_UNSIGNED_BYTE, image_data);
+    }
+
+    GLint err = glGetError();
+
+    //clean up memory and close stuff
+    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+    free(image_data);
+    free(row_pointers);
+    fclose(fp);
+
+    if (err == 0) {
+        //Return physical with and height of texture if pointers are not null
+        if(width) {
+            *width = image_width;
+        }
+        if (height) {
+            *height = image_height;
+        }
+        //Return modified texture coordinates if pointers are not null
+        if(tex_x) {
+            *tex_x = ((float) image_width - 0.5f) / ((float)tex_width);
+        }
+        if(tex_y) {
+            *tex_y = ((float) image_height - 0.5f) / ((float)tex_height);
+        }
+        return EXIT_SUCCESS;
+    } else {
+        fprintf(stderr, "GL error %i \n", err);
+        return EXIT_FAILURE;
+    }
+}
+
+int bbutil_calculate_dpi(screen_context_t ctx) {
+    int rc;
+    int screen_phys_size[2];
+
+    rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_PHYSICAL_SIZE, screen_phys_size);
+    if (rc) {
+        perror("screen_get_display_property_iv");
+        bbutil_terminate();
+        return EXIT_FAILURE;
+    }
+
+    //Simulator will return 0,0 for physical size of the screen, so use 170 as default dpi
+    if ((screen_phys_size[0] == 0) && (screen_phys_size[1] == 0)) {
+        return 170;
+    } else {
+        int screen_resolution[2];
+        rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution);
+        if (rc) {
+            perror("screen_get_display_property_iv");
+            bbutil_terminate();
+            return EXIT_FAILURE;
+        }
+        double diagonal_pixels = sqrt(screen_resolution[0] * screen_resolution[0] + screen_resolution[1] * screen_resolution[1]);
+        double diagonal_inches = 0.0393700787 * sqrt(screen_phys_size[0] * screen_phys_size[0] + screen_phys_size[1] * screen_phys_size[1]);
+        return (int)(diagonal_pixels / diagonal_inches + 0.5);
+
+    }
+}
+
+int bbutil_rotate_screen_surface(int angle) {
+    int rc, rotation, skip = 1, temp;;
+    EGLint interval = 1;
+    int size[2];
+
+    if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) {
+        fprintf(stderr, "Invalid angle\n");
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation);
+    if (rc) {
+        perror("screen_set_window_property_iv");
+        return EXIT_FAILURE;
+    }
+
+    rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
+    if (rc) {
+        perror("screen_set_window_property_iv");
+        return EXIT_FAILURE;
+    }
+
+    switch (angle - rotation) {
+        case -270:
+        case -90:
+        case 90:
+        case 270:
+            temp = size[0];
+            size[0] = size[1];
+            size[1] = temp;
+            skip = 0;
+            break;
+    }
+
+    if (!skip) {
+        rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL);
+        if (rc != EGL_TRUE) {
+            bbutil_egl_perror("eglMakeCurrent");
+            return EXIT_FAILURE;
+        }
+
+        rc = eglDestroySurface(egl_disp, egl_surf);
+        if (rc != EGL_TRUE) {
+            bbutil_egl_perror("eglMakeCurrent");
+            return EXIT_FAILURE;
+        }
+
+        rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size);
+        if (rc) {
+            perror("screen_set_window_property_iv");
+            return EXIT_FAILURE;
+        }
+
+        rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
+        if (rc) {
+            perror("screen_set_window_property_iv");
+            return EXIT_FAILURE;
+        }
+        egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
+        if (egl_surf == EGL_NO_SURFACE) {
+            bbutil_egl_perror("eglCreateWindowSurface");
+            return EXIT_FAILURE;
+        }
+
+        rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
+        if (rc != EGL_TRUE) {
+            bbutil_egl_perror("eglMakeCurrent");
+            return EXIT_FAILURE;
+        }
+
+        rc = eglSwapInterval(egl_disp, interval);
+        if (rc != EGL_TRUE) {
+            bbutil_egl_perror("eglSwapInterval");
+            return EXIT_FAILURE;
+        }
+    }
+
+    rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
+    if (rc) {
+        perror("screen_set_window_property_iv");
+        return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/playbook/src/bbutil.h b/playbook/src/bbutil.h
new file mode 100644
index 0000000000..a8362f91e2
--- /dev/null
+++ b/playbook/src/bbutil.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2011-2012 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UTILITY_H_INCLUDED
+#define _UTILITY_H_INCLUDED
+
+#include <EGL/egl.h>
+#include <screen/screen.h>
+#include <sys/platform.h>
+
+extern EGLDisplay egl_disp;
+extern EGLSurface egl_surf;
+
+typedef struct font_t font_t;
+
+#define BBUTIL_DEFAULT_FONT "/usr/fonts/font_repository/monotype/arial.ttf"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes EGL
+ *
+ * @param libscreen context that will be used for EGL setup
+ * @return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
+ */
+int bbutil_init_egl(screen_context_t ctx);
+
+/**
+ * Terminates EGL
+ */
+void bbutil_terminate();
+
+/**
+ * Swaps default bbutil window surface to the screen
+ */
+void bbutil_swap();
+
+/**
+ * Loads the font from the specified font file.
+ * NOTE: should be called after a successful return from bbutil_init() or bbutil_init_egl() call
+ * @param font_file string indicating the absolute path of the font file
+ * @param point_size used for glyph generation
+ * @param dpi used for glyph generation
+ * @return pointer to font_t structure on success or NULL on failure
+ */
+font_t* bbutil_load_font(const char* font_file, int point_size, int dpi);
+
+/**
+ * Destroys the passed font
+ * @param font to be destroyed
+ */
+void bbutil_destroy_font(font_t* font);
+
+/**
+ * Renders the specified message using current font starting from the specified
+ * bottom left coordinates.
+ * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call
+
+ *
+ * @param font to use for rendering
+ * @param msg the message to display
+ * @param x, y position of the bottom-left corner of text string in world coordinate space
+ * @param rgba color for the text to render with
+ */
+void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r, float g, float b, float a);
+
+/**
+ * Returns the non-scaled width and height of a string
+ * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call
+
+ *
+ * @param font to use for measurement of a string size
+ * @param msg the message to get the size of
+ * @param return pointer for width of a string
+ * @param return pointer for height of a string
+ */
+void bbutil_measure_text(font_t* font, const  char* msg, float* width, float* height);
+
+/**
+ * Creates and loads a texture from a png file
+ * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call
+
+ *
+ * @param filename path to texture png
+ * @param return width of texture
+ * @param return height of texture
+ * @param return gl texture handle
+ * @return EXIT_SUCCESS if texture loading succeeded otherwise EXIT_FAILURE
+ */
+
+int bbutil_load_texture(const char* filename, int* width, int* height, float* tex_x, float* tex_y, unsigned int* tex);
+
+/**
+ * Returns dpi for a given screen
+
+ *
+ * @param ctx path libscreen context that corresponds to display of interest
+ * @return dpi for a given screen
+ */
+
+int bbutil_calculate_dpi(screen_context_t ctx);
+
+/**
+ * Rotates the screen to a given angle
+
+ *
+ * @param angle to rotate screen surface to, must by 0, 90, 180, or 270
+ * @return EXIT_SUCCESS if texture loading succeeded otherwise EXIT_FAILURE
+ */
+
+int bbutil_rotate_screen_surface(int angle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/playbook/src/main.c b/playbook/src/main.c
new file mode 100644
index 0000000000..b738e804c5
--- /dev/null
+++ b/playbook/src/main.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2011-2012 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <assert.h>
+#include <screen/screen.h>
+#include <bps/navigator.h>
+#include <bps/screen.h>
+#include <bps/bps.h>
+#include <bps/event.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+#include <math.h>
+
+#include "bbutil.h"
+
+static GLfloat vertices[8];
+static GLfloat colors[16];
+
+static GLuint program;
+
+static GLuint transformLoc;
+static GLuint positionLoc;
+static GLuint colorLoc;
+
+static GLfloat matrix[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
+
+static GLuint vertexID;
+static GLuint colorID;
+
+static screen_context_t screen_cxt;
+
+
+void handleScreenEvent(bps_event_t *event) {
+    screen_event_t screen_event = screen_event_get_event(event);
+
+    int screen_val;
+    screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
+
+    switch (screen_val) {
+    case SCREEN_EVENT_MTOUCH_TOUCH:
+    case SCREEN_EVENT_MTOUCH_MOVE:
+    case SCREEN_EVENT_MTOUCH_RELEASE:
+        break;
+    }
+}
+
+int initialize() {
+    //Initialize vertex and color data
+    vertices[0] = -0.25f;
+    vertices[1] = -0.25f;
+
+    vertices[2] = 0.25f;
+    vertices[3] = -0.25f;
+
+    vertices[4] = -0.25f;
+    vertices[5] = 0.25f;
+
+    vertices[6] = 0.25f;
+    vertices[7] = 0.25f;
+
+    colors[0] = 1.0f;
+    colors[1] = 0.0f;
+    colors[2] = 1.0f;
+    colors[3] = 1.0f;
+
+    colors[4] = 1.0f;
+    colors[5] = 1.0f;
+    colors[6] = 0.0f;
+    colors[7] = 1.0f;
+
+    colors[8] = 0.0f;
+    colors[9] = 1.0f;
+    colors[10] = 1.0f;
+    colors[11] = 1.0f;
+
+    colors[12] = 0.0f;
+    colors[13] = 1.0f;
+    colors[14] = 1.0f;
+    colors[15] = 1.0f;
+
+    //Query width and height of the window surface created by utility code
+    EGLint surface_width, surface_height;
+
+    eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
+    eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
+
+    // Create shaders
+    const char* vSource =
+            "precision mediump float;"
+            "uniform mat4 u_projection;"
+            "uniform mat4 u_transform;"
+            "attribute vec4 a_position;"
+            "attribute vec4 a_color;"
+            "varying vec4 v_color;"
+            "void main()"
+            "{"
+            "    gl_Position = u_projection * u_transform * a_position;"
+            "    v_color = a_color;"
+            "}";
+
+    const char* fSource =
+            "varying lowp vec4 v_color;"
+            "void main()"
+            "{"
+            "    gl_FragColor = v_color;"
+            "}";
+
+    GLint status;
+
+    // Compile the vertex shader
+    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
+    if (!vs) {
+        fprintf(stderr, "Failed to create vertex shader: %d\n", glGetError());
+        return EXIT_FAILURE;
+    } else {
+        glShaderSource(vs, 1, &vSource, 0);
+        glCompileShader(vs);
+        glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
+        if (GL_FALSE == status) {
+            GLchar log[256];
+            glGetShaderInfoLog(vs, 256, NULL, log);
+
+            fprintf(stderr, "Failed to compile vertex shader: %s\n", log);
+
+            glDeleteShader(vs);
+        }
+    }
+
+    // Compile the fragment shader
+    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
+    if (!fs) {
+        fprintf(stderr, "Failed to create fragment shader: %d\n", glGetError());
+        return EXIT_FAILURE;
+    } else {
+        glShaderSource(fs, 1, &fSource, 0);
+        glCompileShader(fs);
+        glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
+        if (GL_FALSE == status) {
+            GLchar log[256];
+            glGetShaderInfoLog(fs, 256, NULL, log);
+
+            fprintf(stderr, "Failed to compile fragment shader: %s\n", log);
+
+            glDeleteShader(vs);
+            glDeleteShader(fs);
+
+            return EXIT_FAILURE;
+        }
+    }
+
+    // Create and link the program
+    program = glCreateProgram();
+    if (program)
+    {
+        glAttachShader(program, vs);
+        glAttachShader(program, fs);
+        glLinkProgram(program);
+
+        glGetProgramiv(program, GL_LINK_STATUS, &status);
+        if (status == GL_FALSE)    {
+            GLchar log[256];
+            glGetProgramInfoLog(fs, 256, NULL, log);
+
+            fprintf(stderr, "Failed to link shader program: %s\n", log);
+
+            glDeleteProgram(program);
+            program = 0;
+
+            return EXIT_FAILURE;
+        }
+    } else {
+        fprintf(stderr, "Failed to create a shader program\n");
+
+        glDeleteShader(vs);
+        glDeleteShader(fs);
+        return EXIT_FAILURE;
+    }
+
+    glUseProgram(program);
+
+    // Set up the orthographic projection - equivalent to glOrtho in GLES1
+    GLuint projectionLoc = glGetUniformLocation(program, "u_projection");
+    {
+        GLfloat left = 0.0f;
+        GLfloat right = (float)(surface_width) / (float)(surface_height);
+        GLfloat bottom = 0.0f;
+        GLfloat top = 1.0f;
+        GLfloat zNear = -1.0f;
+        GLfloat zFar = 1.0f;
+        GLfloat ortho[16] = {2.0 / (right-left), 0, 0, 0,
+                            0, 2.0 / (top-bottom), 0, 0,
+                            0, 0, -2.0 / (zFar - zNear), 0,
+                            -(right+left)/(right-left), -(top+bottom)/(top-bottom), -(zFar+zNear)/(zFar-zNear), 1};
+        glUniformMatrix4fv(projectionLoc, 1, false, ortho);
+    }
+
+    // Store the locations of the shader variables we need later
+    transformLoc = glGetUniformLocation(program, "u_transform");
+    positionLoc = glGetAttribLocation(program, "a_position");
+    colorLoc = glGetAttribLocation(program, "a_color");
+
+    // We don't need the shaders anymore - the program is enough
+    glDeleteShader(fs);
+    glDeleteShader(vs);
+
+    // Generate vertex and color buffers and fill with data
+    glGenBuffers(1, &vertexID);
+    glBindBuffer(GL_ARRAY_BUFFER, vertexID);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+    glGenBuffers(1, &colorID);
+    glBindBuffer(GL_ARRAY_BUFFER, colorID);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
+
+    // Perform the same translation as the GLES1 version
+    matrix[12] = (float)(surface_width) / (float)(surface_height) / 2;
+    matrix[13] = 0.5;
+    glUniformMatrix4fv(transformLoc, 1, false, matrix);
+
+    return EXIT_SUCCESS;
+}
+
+void render() {
+    // Increment the angle by 0.5 degrees
+    static float angle = 0.0f;
+    angle += 0.5f * M_PI / 180.0f;
+
+    //Typical render pass
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    // Enable and bind the vertex information
+    glEnableVertexAttribArray(positionLoc);
+    glBindBuffer(GL_ARRAY_BUFFER, vertexID);
+    glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
+
+    // Enable and bind the color information
+    glEnableVertexAttribArray(colorLoc);
+    glBindBuffer(GL_ARRAY_BUFFER, colorID);
+    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
+
+    // Effectively apply a rotation of angle about the y-axis.
+    matrix[0] = cos(angle);
+    matrix[2] = -sin(angle);
+    matrix[8] = sin(angle);
+    matrix[10] = cos(angle);
+    glUniformMatrix4fv(transformLoc, 1, false, matrix);
+
+    // Same draw call as in GLES1.
+    glDrawArrays(GL_TRIANGLE_STRIP, 0 , 4);
+
+    // Disable attribute arrays
+    glDisableVertexAttribArray(positionLoc);
+    glDisableVertexAttribArray(colorLoc);
+
+    bbutil_swap();
+}
+
+int main(int argc, char *argv[]) {
+    int rc;
+    int exit_application = 0;
+
+    //Create a screen context that will be used to create an EGL surface to to receive libscreen events
+    screen_create_context(&screen_cxt, 0);
+
+    //Initialize BPS library
+    bps_initialize();
+
+    //Use utility code to initialize EGL for rendering with GL ES 2.0
+    if (EXIT_SUCCESS != bbutil_init_egl(screen_cxt)) {
+        fprintf(stderr, "bbutil_init_egl failed\n");
+        bbutil_terminate();
+        screen_destroy_context(screen_cxt);
+        return 0;
+    }
+
+    //Initialize application logic
+    if (EXIT_SUCCESS != initialize()) {
+        fprintf(stderr, "initialize failed\n");
+        bbutil_terminate();
+        screen_destroy_context(screen_cxt);
+        bps_shutdown();
+        return 0;
+    }
+
+    //Signal BPS library that navigator and screen events will be requested
+    if (BPS_SUCCESS != screen_request_events(screen_cxt)) {
+        fprintf(stderr, "screen_request_events failed\n");
+        bbutil_terminate();
+        screen_destroy_context(screen_cxt);
+        bps_shutdown();
+        return 0;
+    }
+
+    if (BPS_SUCCESS != navigator_request_events(0)) {
+        fprintf(stderr, "navigator_request_events failed\n");
+        bbutil_terminate();
+        screen_destroy_context(screen_cxt);
+        bps_shutdown();
+        return 0;
+    }
+
+    //Signal BPS library that navigator orientation is not to be locked
+    if (BPS_SUCCESS != navigator_rotation_lock(false)) {
+        fprintf(stderr, "navigator_rotation_lock failed\n");
+        bbutil_terminate();
+        screen_destroy_context(screen_cxt);
+        bps_shutdown();
+        return 0;
+    }
+
+    while (!exit_application) {
+        //Request and process all available BPS events
+        bps_event_t *event = NULL;
+
+        for(;;) {
+            rc = bps_get_event(&event, 0);
+            assert(rc == BPS_SUCCESS);
+
+            if (event) {
+                int domain = bps_event_get_domain(event);
+
+                if (domain == screen_get_domain()) {
+                    handleScreenEvent(event);
+                } else if ((domain == navigator_get_domain())
+                        && (NAVIGATOR_EXIT == bps_event_get_code(event))) {
+                    exit_application = 1;
+                }
+            } else {
+                break;
+            }
+        }
+        render();
+    }
+
+    //Stop requesting events from libscreen
+    screen_stop_events(screen_cxt);
+
+    //Shut down BPS library for this process
+    bps_shutdown();
+
+    //Use utility code to terminate EGL setup
+    bbutil_terminate();
+
+    //Destroy libscreen context
+    screen_destroy_context(screen_cxt);
+    return 0;
+}