diff --git a/.gitignore b/.gitignore index 3388eca8ca..788ce5e246 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,9 @@ *.pyc *.pyo +*.apk .packages python_for_android.egg-info /build/ +doc/build __pycache__/ diff --git a/README.md b/README.md index c20715c5b2..7bbb8f5dfc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Broad goals of the revamp project include: - ✓ Support SDL2 - ✓ Support multiple bootstraps (user-chosen java + NDK code, e.g. for multiple graphics backends or non-Kivy projects) -- (WIP) Support python3 (recipe exists but crashes on android) +- ✓ Support python3 (it finally works!) - (WIP) Support some kind of binary distribution, including on windows (semi-implemented, just needs finishing) - ✓ Be a standalone Pypi module (not on pypi yet but setup.py works) - ✓ Support multiple architectures (full multiarch builds not complete, but arm and x86 with different config both work now) diff --git a/doc/source/bootstraps.rst b/doc/source/bootstraps.rst index d38566da2d..17b36a3387 100644 --- a/doc/source/bootstraps.rst +++ b/doc/source/bootstraps.rst @@ -11,56 +11,12 @@ components such as Android source code and various build files. If you do not want to modify p4a, you don't need to worry about bootstraps, just make sure you specify what modules you want to use (or specify an existing bootstrap manually), and p4a will -automatically build everything appropriately. +automatically build everything appropriately. The existing choices are +explained on the :ref:`build options ` page. This page describes the basics of how bootstraps work so that you can create and use your own if you like, making it easy to build new kinds of Python project for Android. - - -Current bootstraps ------------------- - -python-for-android includes the following bootstraps by default, which -may be chosen by name with a build parameter, or (by default) are -selected automatically in order to fulfil your build requirements. For -instance, if you add 'sdl2' in the requirements, the sdl2 backend will -be used. - -p4a is designed to make it fairly easy to make your own bootstrap with a new backend, -e.g. one that creates a webview interface and runs python in the -background to serve a flask or django site from the phone itself. - - -pygame -%%%%%% - -This builds APKs exactly like the old p4a toolchain, using Pygame as -the windowing and input backend. - -This bootstrap automatically includes pygame, kivy, and python. It -could potentially be modified to work for non-Kivy projects. - -sdl2 -%%%% - -This builds APKs using SDL2 as the window and input backend. It is not -fully developed compared to the Pygame backend, but has many -advantages and will be the long term default. - -This bootstrap automatically includes SDL2, but nothing else. - -You can use the sdl2 bootstrap to seamlessly make a Kivy APK, but can -also make Python apps using other libraries; for instance, using -pysdl2 and pyopengl. `Vispy `_ also runs on android -this way. - -empty -%%%%% - -This bootstrap has no dependencies and cannot actually build an -APK. It is useful for testing recipes without building unnecessary -components. Creating a new bootstrap diff --git a/doc/source/buildoptions.rst b/doc/source/buildoptions.rst new file mode 100644 index 0000000000..e55fc66241 --- /dev/null +++ b/doc/source/buildoptions.rst @@ -0,0 +1,108 @@ + +Build options +============= + +python-for-android provides several major choices for build +components. This page describes the advantages and drawbacks, and +extra technical details or requirements, in each case. + + +Python version +-------------- + +python-for-android now supports building APKs with either python2 or +python3, but these have extra requirements or potential disadvantages +as below. + + +python2 +~~~~~~~ + +Select this by adding it in your requirements, e.g. ``--requirements=python2``. + +This option builds Python 2.7.2 for your selected Android architecture, and +includes it in the APK. There are no special requirements, all the +building is done locally. + +The python2 build is also the way python-for-android originally +worked, even in the old toolchain. + + +python3 +~~~~~~~ + +.. warning:: + Python3 support is experimental, and some of these details + may change as it is improved and fully stabilised. + +Select this by adding the ``python3crystax`` recipe to your +requirements, e.g. ``--requirements=python3crystax``. + +This uses the prebuilt Python from the `CrystaX NDK +`__, a drop-in replacement for +Google's official NDK which includes many improvements. As such, you +*must* use the CrystaX NDK 10.3.0 or higher when building with +python3. You can get it `here +`__. + +python3 inclusion should work fine, including all existing +recipes, but internally this is handled quite differently to the +locally built python2 so there may be bugs or surprising +behaviours. If you come across any, feel free to `open an issue +`__. + +The experimental status also means that some features are missing and +the build is not fully optimised so APKs are probably a little larger +and slower than they need to be. This is currently being addressed, +though it's not clear how the final result will compare to python2. + +.. _bootstrap_build_options: + +Bootstrap +--------- + +python-for-android supports multiple bootstraps, the Java and JNI code +that starts the app and the python interpreter, then handles +interactions with the Android OS. + +Currently the following bootstraps are supported, but we hope that it +it should be easy to add others if your project has different +requirements. `Let us know +`__ if there +are any improvements that would help here. + +sdl2 +~~~~ + +You can use this with ``--bootstrap=sdl2``, or simply include the +``sdl2`` recipe in your ``--requirements``. + +SDL2 is a popular cross-platform depelopment library, particularly for +games. It has its own Android project support, which +python-for-android uses as a bootstrap, and to which it adds the +Python build and JNI code to start it. + +From the point of view of a Python program, SDL2 should behave as +normal. For instance, you can build apps with Kivy, Vispy, or PySDL2 +and have them work with this bootstrap. It should also be possible to +use e.g. pygame_sdl2, but this would need a build recipe and doesn't +yet have one. + +.. note:: + The SDL2 bootstrap is newer, and does not support all the old + features of the Pygame one. It is under active development to fix + these omissions. + +pygame +~~~~~~ + +You can use this with ``--bootstrap=pygame``, or simply include the +``pygame`` recipe in your ``--requirements``. + +The pygame bootstrap is the original backend used by Kivy, and still +works fine for use with Kivy apps. It may also work for pure pygame +apps, but hasn't been developed with this in mind. + +This bootstrap will eventually be deprecated in favour of sdl2, but +not before the sdl2 bootstrap includes all the features that would be +lost. diff --git a/doc/source/commands.rst b/doc/source/commands.rst index 57d11994b1..b6d6bc7fc4 100644 --- a/doc/source/commands.rst +++ b/doc/source/commands.rst @@ -73,6 +73,14 @@ supply those that you need. ``--arch`` The architecture to build for. Currently only one architecture can be targeted at a time, and a given distribution can only include one architecture. + +``--bootstrap BOOTSTRAP`` + + The Java bootstrap to use for your application. You mostly don't + need to worry about this or set it manually, as an appropriate + bootstrap will be chosen from your ``--requirements``. Current + choices are ``sdl2`` or ``pygame``; ``sdl2`` is experimental but + preferable where possible. .. note:: These options are preliminary. Others will include toggles diff --git a/doc/source/index.rst b/doc/source/index.rst index a37363d4e8..451999e02c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -27,13 +27,13 @@ Contents :maxdepth: 2 quickstart + buildoptions installation commands recipes bootstraps apis troubleshooting - old_p4a contribute old_toolchain/index.rst diff --git a/doc/source/old_p4a.rst b/doc/source/old_p4a.rst deleted file mode 100644 index cc299130b5..0000000000 --- a/doc/source/old_p4a.rst +++ /dev/null @@ -1,14 +0,0 @@ - -Differences to the old python-for-android project -================================================= - -This python-for-android project is a rewrite, and eventual -replacement, for Kivy's existing python-for-android project. This -project existed for some time and, although it is now close to -deprecated, there are many resources discussing how to use it. - -For this reason, the following documentation gives a basic explanation -of how to accomplish that previously used the ``distribute.sh`` and -``build.py`` toolchain with this new one. - - diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst index 5a30aaf72b..c40799e146 100644 --- a/doc/source/quickstart.rst +++ b/doc/source/quickstart.rst @@ -144,8 +144,9 @@ You can build an SDL2 APK similarly, creating a dist as follows:: You can then make an APK in the same way, but this is more experimental and doesn't support as much customisation yet. -There is also experimental support for building APKs with Vispy, which -do not include Kivy. The basic command for this would be e.g.:: +Your APKs are not limited to Kivy, for instance you can create apps +using Vispy, or using PySDL2 directly. The basic command for this +would be e.g.:: python-for-android create --dist_name=testvispy --bootstrap=sdl2 --requirements=vispy diff --git a/doc/source/recipes.rst b/doc/source/recipes.rst index 444ecb3210..5a1212a111 100644 --- a/doc/source/recipes.rst +++ b/doc/source/recipes.rst @@ -38,6 +38,8 @@ The basic declaration of a recipe is as follows:: url = 'http://example.com/example-{version}.tar.gz' version = '2.0.3' md5sum = '4f3dc9a9d857734a488bcbefd9cd64ed' + + patches = ['some_fix.patch'] # Paths relative to the recipe dir depends = ['kivy', 'sdl2'] # These are just examples conflicts = ['pygame'] @@ -118,26 +120,35 @@ Methods and tools to help with compilation Patching modules before installation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can easily apply patches to your recipes with the ``apply_patch`` -method. For instance, you could do this in your prebuild method:: +You can easily apply patches to your recipes by adding them to the +``patches`` declaration, e.g.:: + + patches = ['some_fix.patch', + 'another_fix.patch'] + +The paths should be relative to the recipe file. Patches are +automatically applied just once (i.e. not reapplied the second time +python-for-android is run). + +You can also use the helper functions in ``pythonforandroid.patching`` +to apply patches depending on certain conditions, e.g.:: + + from pythonforandroid.patching import will_build, is_arch - import sh - def prebuild_arch(self, arch): - super(YourRecipe, self).prebuild_arch(arch) - build_dir = self.get_build_dir(arch.arch) - if exists(join(build_dir, '.patched')): - print('Your recipe is already patched, skipping') - return - self.apply_patch('some_patch.patch') - shprint(sh.touch, join(build_dir, '.patched')) + ... -The path to the patch should be in relation to your recipe code. -In this case, ``some_path.patch`` must be in the same directory as the -recipe. + class YourRecipe(Recipe): + + patches = [('x86_patch.patch', is_arch('x86')), + ('sdl2_compatibility.patch', will_build('sdl2'))] + + ... + +You can include your own conditions by passing any function as the +second entry of the tuple. It will receive the ``arch`` (e.g. x86, +armeabi) and ``recipe`` (i.e. the Recipe object) as kwargs. The patch +will be applied only if the function returns True. -This code also manually takes care to patch only once. You can use the -same strategy yourself, though a more generic solution may be provided -in the future. Installing libs ~~~~~~~~~~~~~~~ @@ -210,29 +221,28 @@ The should_build method ~~~~~~~~~~~~~~~~~~~~~~~ The Recipe class has a ``should_build`` method, which returns a -boolean. This is called before running ``build_arch``, and if it -returns False then the build is skipped. This is useful to avoid -building a recipe more than once for different dists. +boolean. This is called for each architecture before running +``build_arch``, and if it returns False then the build is +skipped. This is useful to avoid building a recipe more than once for +different dists. By default, should_build returns True, but you can override it however you like. For instance, PythonRecipe and its subclasses all replace it with a check for whether the recipe is already installed in the Python distribution:: - def should_build(self): + def should_build(self, arch): name = self.site_packages_name if name is None: name = self.name - if exists(join(self.ctx.get_site_packages_dir(), name)): + if self.ctx.has_package(name): info('Python package already exists in site-packages') return False - print('site packages', self.ctx.get_site_packages_dir()) info('{} apparently isn\'t already in site-packages'.format(name)) return True - Using a PythonRecipe -------------------- @@ -463,12 +473,11 @@ The above documentation has included a number of snippets demonstrating different behaviour. Together, these cover most of what is ever necessary to make a recipe work. -The following short sections further demonstrate a few full recipes from p4a's -internal recipes folder. Unless your own module has some unusual -complication, following these templates should be all you need to make -your own recipes work. +python-for-android includes many recipes for popular modules, which +are an excellent resource to find out how to add your own. You can +find these in the `python-for-android Github page +`__. -TODO .. _recipe_class: diff --git a/pythonforandroid/archs.py b/pythonforandroid/archs.py index 0a42713e60..6ba70be6d0 100644 --- a/pythonforandroid/archs.py +++ b/pythonforandroid/archs.py @@ -84,6 +84,8 @@ def get_env(self): env['AR'] = '{}-ar'.format(command_prefix) env['RANLIB'] = '{}-ranlib'.format(command_prefix) env['LD'] = '{}-ld'.format(command_prefix) + # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + # env['LDSHARED'] = env['LD'] env['STRIP'] = '{}-strip --strip-unneeded'.format(command_prefix) env['MAKE'] = 'make -j5' env['READELF'] = '{}-readelf'.format(command_prefix) @@ -100,6 +102,9 @@ def get_env(self): env['ARCH'] = self.arch + if self.ctx.python_recipe.from_crystax: + env['CRYSTAX_PYTHON_VERSION'] = self.ctx.python_recipe.version + return env diff --git a/pythonforandroid/bootstrap.py b/pythonforandroid/bootstrap.py index cedf50df28..8f4ddf75a6 100644 --- a/pythonforandroid/bootstrap.py +++ b/pythonforandroid/bootstrap.py @@ -53,8 +53,27 @@ def dist_dir(self): def jni_dir(self): return self.name + self.jni_subdir + def check_recipe_choices(self): + '''Checks what recipes are being built to see which of the alternative + and optional dependencies are being used, + and returns a list of these.''' + recipes = [] + built_recipes = self.ctx.recipe_build_order + for recipe in self.recipe_depends: + if isinstance(recipe, (tuple, list)): + for alternative in recipe: + if alternative in built_recipes: + recipes.append(alternative) + break + return sorted(recipes) + + def get_build_dir_name(self): + choices = self.check_recipe_choices() + dir_name = '-'.join([self.name] + choices) + return dir_name + def get_build_dir(self): - return join(self.ctx.build_dir, 'bootstrap_builds', self.name) + return join(self.ctx.build_dir, 'bootstrap_builds', self.get_build_dir_name()) def get_dist_dir(self, name): return join(self.ctx.dist_dir, name) @@ -216,6 +235,9 @@ def _unpack_aar(self, aar, arch): def strip_libraries(self, arch): info('Stripping libraries') + if self.ctx.python_recipe.from_crystax: + info('Python was loaded from CrystaX, skipping strip') + return env = arch.get_env() strip = which('arm-linux-androideabi-strip', env['PATH']) if strip is None: diff --git a/pythonforandroid/bootstraps/pygame/build/build.py b/pythonforandroid/bootstraps/pygame/build/build.py index 95f80a0444..e453a54086 100755 --- a/pythonforandroid/bootstraps/pygame/build/build.py +++ b/pythonforandroid/bootstraps/pygame/build/build.py @@ -68,7 +68,7 @@ def render(template, dest, **kwargs): template = environment.get_template(template) text = template.render(**kwargs) - f = file(dest, 'wb') + f = open(dest, 'wb') f.write(text.encode('utf-8')) f.close() @@ -224,9 +224,9 @@ def make_package(args): args.numeric_version = str(version_code) - args.name = args.name.decode('utf-8') - if args.icon_name: - args.icon_name = args.icon_name.decode('utf-8') + # args.name = args.name.decode('utf-8') + # if args.icon_name: + # args.icon_name = args.icon_name.decode('utf-8') versioned_name = (args.name.replace(' ', '').replace('\'', '') + '-' + args.version) @@ -306,8 +306,8 @@ def make_package(args): subprocess.call([ANDROID, 'update', 'project', '-p', '.', '-t', 'android-{}'.format(args.sdk_version)]) except (OSError, IOError): - print 'An error occured while calling', ANDROID, 'update' - print 'Your PATH must include android tools.' + print('An error occured while calling', ANDROID, 'update') + print('Your PATH must include android tools.') sys.exit(-1) # Delete the old assets. @@ -346,7 +346,7 @@ def make_package(args): if args.add_jar: for jarname in args.add_jar: if not os.path.exists(jarname): - print 'Requested jar does not exist: {}'.format(jarname) + print('Requested jar does not exist: {}'.format(jarname)) sys.exit(-1) shutil.copy(jarname, 'libs') @@ -355,8 +355,8 @@ def make_package(args): for arg in args.command: subprocess.check_call([ANT, arg]) except (OSError, IOError): - print 'An error occured while calling', ANT - print 'Did you install ant on your system ?' + print('An error occured while calling', ANT) + print('Did you install ant on your system ?') sys.exit(-1) def parse_args(args=None): diff --git a/pythonforandroid/bootstraps/sdl2/__init__.py b/pythonforandroid/bootstraps/sdl2/__init__.py index 33871a2d10..54e17929e4 100644 --- a/pythonforandroid/bootstraps/sdl2/__init__.py +++ b/pythonforandroid/bootstraps/sdl2/__init__.py @@ -7,7 +7,7 @@ class SDL2Bootstrap(Bootstrap): name = 'sdl2' - recipe_depends = ['sdl2'] + recipe_depends = ['sdl2', ('python2', 'python3crystax')] def run_distribute(self): info_main('# Creating Android project from build and {} bootstrap'.format( @@ -28,57 +28,83 @@ def run_distribute(self): with current_directory(self.dist_dir): info('Copying python distribution') - if not exists('private'): + if not exists('private') and not self.ctx.python_recipe.from_crystax: shprint(sh.mkdir, 'private') + if not exists('crystax_python') and self.ctx.python_recipe.from_crystax: + shprint(sh.mkdir, 'crystax_python') + shprint(sh.mkdir, 'crystax_python/crystax_python') if not exists('assets'): shprint(sh.mkdir, 'assets') hostpython = sh.Command(self.ctx.hostpython) - shprint(hostpython, '-OO', '-m', 'compileall', - self.ctx.get_python_install_dir(), - _tail=10, _filterout="^Listing", _critical=True) - if not exists('python-install'): - shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install') + if not self.ctx.python_recipe.from_crystax: + shprint(hostpython, '-OO', '-m', 'compileall', + self.ctx.get_python_install_dir(), + _tail=10, _filterout="^Listing", _critical=True) + if not exists('python-install'): + shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install') self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)]) self.distribute_aars(arch) self.distribute_javaclasses(self.ctx.javaclass_dir) - info('Filling private directory') - if not exists(join('private', 'lib')): - info('private/lib does not exist, making') - shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') - shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7')) + if not self.ctx.python_recipe.from_crystax: + info('Filling private directory') + if not exists(join('private', 'lib')): + info('private/lib does not exist, making') + shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') + shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7')) - # AND: Copylibs stuff should go here - if exists(join('libs', arch.arch, 'libpymodules.so')): - shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/') - shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/')) - - info('Removing some unwanted files') - shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so')) - shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) - - with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')): - # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) - removes = [] - for dirname, something, filens in walk('.'): - for filename in filens: - for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): - if filename.endswith(suffix): - removes.append(filename) - shprint(sh.rm, '-f', *removes) - - info('Deleting some other stuff not used on android') - # To quote the original distribute.sh, 'well...' - # shprint(sh.rm, '-rf', 'ctypes') - shprint(sh.rm, '-rf', 'lib2to3') - shprint(sh.rm, '-rf', 'idlelib') - for filename in glob.glob('config/libpython*.a'): - shprint(sh.rm, '-f', filename) - shprint(sh.rm, '-rf', 'config/python.o') - # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') - # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') + # AND: Copylibs stuff should go here + if exists(join('libs', arch.arch, 'libpymodules.so')): + shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/') + shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/')) + + info('Removing some unwanted files') + shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so')) + shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) + + with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')): + # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) + removes = [] + for dirname, something, filens in walk('.'): + for filename in filens: + for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): + if filename.endswith(suffix): + removes.append(filename) + shprint(sh.rm, '-f', *removes) + + info('Deleting some other stuff not used on android') + # To quote the original distribute.sh, 'well...' + # shprint(sh.rm, '-rf', 'ctypes') + shprint(sh.rm, '-rf', 'lib2to3') + shprint(sh.rm, '-rf', 'idlelib') + for filename in glob.glob('config/libpython*.a'): + shprint(sh.rm, '-f', filename) + shprint(sh.rm, '-rf', 'config/python.o') + # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') + # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') + + else: # Python *is* loaded from crystax + ndk_dir = self.ctx.ndk_dir + py_recipe = self.ctx.python_recipe + python_dir = join(ndk_dir, 'sources', 'python', py_recipe.version, + 'libs', arch.arch) + + shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/crystax_python') + shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/crystax_python') + shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/crystax_python/site-packages') + + info('Renaming .so files to reflect cross-compile') + site_packages_dir = 'crystax_python/crystax_python/site-packages' + filens = shprint(sh.find, site_packages_dir, '-iname', '*.so').stdout.decode( + 'utf-8').split('\n')[:-1] + for filen in filens: + parts = filen.split('.') + if len(parts) <= 2: + continue + shprint(sh.mv, filen, filen.split('.')[0] + '.so') + self.strip_libraries(arch) super(SDL2Bootstrap, self).run_distribute() diff --git a/pythonforandroid/bootstraps/sdl2/build/build.py b/pythonforandroid/bootstraps/sdl2/build/build.py index 16c53b6683..9249491d51 100755 --- a/pythonforandroid/bootstraps/sdl2/build/build.py +++ b/pythonforandroid/bootstraps/sdl2/build/build.py @@ -2,7 +2,7 @@ from __future__ import print_function -from os.path import dirname, join, isfile, realpath, relpath, split +from os.path import dirname, join, isfile, realpath, relpath, split, exists import os import tarfile import time @@ -107,6 +107,12 @@ def make_python_zip(): # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html site-packages, config and lib-dynload will be not included. ''' + + if not exists('private'): + print('No compiled python is present to zip, skipping.') + print('this should only be the case if you are using the CrystaX python') + return + global python_files d = realpath(join('private', 'lib', 'python2.7')) @@ -215,13 +221,18 @@ def make_package(args): os.unlink('assets/private.mp3') # In order to speedup import and initial depack, - # construct a python27.zip + # construct a python27.zip if not using CrystaX's pre-zipped package make_python_zip() # Package up the private and public data. # AND: Just private for now + tar_dirs = [args.private] + if exists('private'): + tar_dirs.append('private') + if exists('crystax_python'): + tar_dirs.append('crystax_python') if args.private: - make_tar('assets/private.mp3', ['private', args.private], args.ignore_path) + make_tar('assets/private.mp3', tar_dirs, args.ignore_path) # else: # make_tar('assets/private.mp3', ['private']) diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk index 6c90a3b818..5d2120f2c0 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk @@ -14,10 +14,14 @@ LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 -LOCAL_SHARED_LIBRARIES := SDL2 +LOCAL_SHARED_LIBRARIES := SDL2 python_shared -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lpython2.7 +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog $(EXTRA_LDLIBS) LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) include $(BUILD_SHARED_LIBRARY) + +ifdef CRYSTAX_PYTHON_VERSION + $(call import-module,python/$(CRYSTAX_PYTHON_VERSION)) +endif diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index 5119d92b82..40ba1ab3b1 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -8,7 +8,12 @@ #include #include #include +#include #include +#include +#include + +#include #include "SDL.h" @@ -39,10 +44,61 @@ static PyMethodDef AndroidEmbedMethods[] = { {NULL, NULL, 0, NULL} }; -PyMODINIT_FUNC initandroidembed(void) { - (void) Py_InitModule("androidembed", AndroidEmbedMethods); + +#if PY_MAJOR_VERSION >= 3 + static struct PyModuleDef androidembed = + { + PyModuleDef_HEAD_INIT, + "androidembed", + "", + -1, + AndroidEmbedMethods + }; + + PyMODINIT_FUNC initandroidembed(void) { + return PyModule_Create(&androidembed); + /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ + } +#else + PyMODINIT_FUNC initandroidembed(void) { + (void) Py_InitModule("androidembed", AndroidEmbedMethods); + } +#endif + +/* int dir_exists(char* filename) */ +/* /\* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# *\/ */ +/* { */ +/* if (0 != access(filename, F_OK)) { */ +/* if (ENOENT == errno) { */ +/* return 0; */ +/* } */ +/* if (ENOTDIR == errno) { */ +/* return 0; */ +/* } */ +/* return 1; */ +/* } */ +/* } */ + +/* int dir_exists(char* filename) { */ +/* DIR *dip; */ +/* if (dip = opendir(filename)) { */ +/* closedir(filename); */ +/* return 1; */ +/* } */ +/* return 0; */ +/* } */ + + +int dir_exists(char *filename) { + struct stat st; + if (stat(filename, &st) == 0) { + if (S_ISDIR(st.st_mode)) + return 1; + } + return 0; } + int file_exists(const char * filename) { FILE *file; @@ -78,38 +134,94 @@ int main(int argc, char *argv[]) { /* LOG(argv[0]); */ /* LOG("AND: That was argv 0"); */ //setenv("PYTHONVERBOSE", "2", 1); - Py_SetProgramName(argv[0]); + + LOG("Changing directory to the one provided by ANDROID_ARGUMENT"); + LOG(env_argument); + chdir(env_argument); + + Py_SetProgramName(L"android_python"); + +#if PY_MAJOR_VERSION >= 3 + /* our logging module for android + */ + PyImport_AppendInittab("androidembed", initandroidembed); +#endif + + LOG("Preparing to initialize python"); + + if (dir_exists("crystax_python/")) { + LOG("crystax_python exists"); + char paths[256]; + snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); + /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */ + LOG("calculated paths to be..."); + LOG(paths); + +#if PY_MAJOR_VERSION >= 3 + wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); + Py_SetPath(wchar_paths); +#else + char* wchar_paths = paths; + LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); + exit(1); +#endif + + LOG("set wchar paths..."); + } else { LOG("crystax_python does not exist");} + Py_Initialize(); + +#if PY_MAJOR_VERSION < 3 PySys_SetArgv(argc, argv); +#endif - LOG("AND: Set program name"); + LOG("Initialized python"); /* ensure threads will work. */ - PyEval_InitThreads(); - LOG("AND: Init threads"); + PyEval_InitThreads(); + - /* our logging module for android - */ +#if PY_MAJOR_VERSION < 3 initandroidembed(); +#endif - LOG("AND: Init embed"); + PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ + PyRun_SimpleString("import sys, posix\n"); + if (dir_exists("lib")) { + /* If we built our own python, set up the paths correctly */ + LOG("Setting up python from ANDROID_PRIVATE"); + PyRun_SimpleString( + "private = posix.environ['ANDROID_PRIVATE']\n" \ + "argument = posix.environ['ANDROID_ARGUMENT']\n" \ + "sys.path[:] = [ \n" \ + " private + '/lib/python27.zip', \n" \ + " private + '/lib/python2.7/', \n" \ + " private + '/lib/python2.7/lib-dynload/', \n" \ + " private + '/lib/python2.7/site-packages/', \n" \ + " argument ]\n"); + } + + if (dir_exists("crystax_python")) { + char add_site_packages_dir[256]; + snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", + env_argument); + + PyRun_SimpleString( + "import sys\n" \ + "sys.argv = ['notaninterpreterreally']\n" \ + "from os.path import realpath, join, dirname"); + PyRun_SimpleString(add_site_packages_dir); + /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ + PyRun_SimpleString("sys.path = ['.'] + sys.path"); + } + PyRun_SimpleString( - "import sys, posix\n" \ - "private = posix.environ['ANDROID_PRIVATE']\n" \ - "argument = posix.environ['ANDROID_ARGUMENT']\n" \ - "sys.path[:] = [ \n" \ - " private + '/lib/python27.zip', \n" \ - " private + '/lib/python2.7/', \n" \ - " private + '/lib/python2.7/lib-dynload/', \n" \ - " private + '/lib/python2.7/site-packages/', \n" \ - " argument ]\n" \ - "import androidembed\n" \ "class LogFile(object):\n" \ " def __init__(self):\n" \ " self.buffer = ''\n" \ @@ -122,15 +234,43 @@ int main(int argc, char *argv[]) { " def flush(self):\n" \ " return\n" \ "sys.stdout = sys.stderr = LogFile()\n" \ - "import site; print site.getsitepackages()\n"\ - "print 'Android path', sys.path\n" \ - "print 'Android kivy bootstrap done. __name__ is', __name__"); + "print('Android path', sys.path)\n" \ + "import os\n" \ + "print('os.environ is', os.environ)\n" \ + "print('Android kivy bootstrap done. __name__ is', __name__)"); + + /* PyRun_SimpleString( */ + /* "import sys, posix\n" \ */ + /* "private = posix.environ['ANDROID_PRIVATE']\n" \ */ + /* "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */ + /* "sys.path[:] = [ \n" \ */ + /* " private + '/lib/python27.zip', \n" \ */ + /* " private + '/lib/python2.7/', \n" \ */ + /* " private + '/lib/python2.7/lib-dynload/', \n" \ */ + /* " private + '/lib/python2.7/site-packages/', \n" \ */ + /* " argument ]\n" \ */ + /* "import androidembed\n" \ */ + /* "class LogFile(object):\n" \ */ + /* " def __init__(self):\n" \ */ + /* " self.buffer = ''\n" \ */ + /* " def write(self, s):\n" \ */ + /* " s = self.buffer + s\n" \ */ + /* " lines = s.split(\"\\n\")\n" \ */ + /* " for l in lines[:-1]:\n" \ */ + /* " androidembed.log(l)\n" \ */ + /* " self.buffer = lines[-1]\n" \ */ + /* " def flush(self):\n" \ */ + /* " return\n" \ */ + /* "sys.stdout = sys.stderr = LogFile()\n" \ */ + /* "import site; print site.getsitepackages()\n"\ */ + /* "print 'Android path', sys.path\n" \ */ + /* "print 'Android kivy bootstrap done. __name__ is', __name__"); */ LOG("AND: Ran string"); + /* run it ! */ LOG("Run user program, change dir and execute main.py"); - chdir(env_argument); /* search the initial main.py */ @@ -160,8 +300,9 @@ int main(int argc, char *argv[]) { if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ - if (Py_FlushLine()) - PyErr_Clear(); + PyObject *f = PySys_GetObject("stdout"); + if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ + PyErr_Clear(); } /* close everything diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c deleted file mode 100644 index ef9f38d607..0000000000 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - Copyright (r) 1997-2014 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES2 -#endif - -#ifdef HAVE_OPENGLES2 - -#include "SDL_opengles2.h" - -typedef struct GLES2_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC -} GLES2_Context; - - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; -static GLES2_Context ctx; - -static int LoadContext(GLES2_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* _SDL_NOGETPROCADDR_ */ - -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC - return 0; -} - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -#define GL_CHECK(x) \ - x; \ - { \ - GLenum glError = ctx.glGetError(); \ - if(glError != GL_NO_ERROR) { \ - SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ - quit(1); \ - } \ - } - -/* - * Simulates desktop's glRotatef. The matrix is returned in column-major - * order. - */ -static void -rotate_matrix(double angle, double x, double y, double z, float *r) -{ - double radians, c, s, c1, u[3], length; - int i, j; - - radians = (angle * M_PI) / 180.0; - - c = cos(radians); - s = sin(radians); - - c1 = 1.0 - cos(radians); - - length = sqrt(x * x + y * y + z * z); - - u[0] = x / length; - u[1] = y / length; - u[2] = z / length; - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[15] = 1.0; - - for (i = 0; i < 3; i++) { - r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; - r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; - } - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0); - } - } -} - -/* - * Simulates gluPerspectiveMatrix - */ -static void -perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r) -{ - int i; - double f; - - f = 1.0/tan(fovy * 0.5); - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[0] = f / aspect; - r[5] = f; - r[10] = (znear + zfar) / (znear - zfar); - r[11] = -1.0; - r[14] = (2.0 * znear * zfar) / (znear - zfar); - r[15] = 0.0; -} - -/* - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column - * major. In-place multiplication is supported. - */ -static void -multiply_matrix(float *lhs, float *rhs, float *r) -{ - int i, j, k; - float tmp[16]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - tmp[j * 4 + i] = 0.0; - - for (k = 0; k < 4; k++) { - tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; - } - } - } - - for (i = 0; i < 16; i++) { - r[i] = tmp[i]; - } -} - -/* - * Create shader, load in source, compile, dump debug as necessary. - * - * shader: Pointer to return created shader ID. - * source: Passed-in shader source code. - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. - */ -void -process_shader(GLuint *shader, const char * source, GLint shader_type) -{ - GLint status = GL_FALSE; - const char *shaders[1] = { NULL }; - - /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); - - shaders[0] = source; - - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); - - /* Clean up shader source. */ - shaders[0] = NULL; - - /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); - - // Dump debug info (source and log) if compilation failed. - if(status != GL_TRUE) { - SDL_Log("Shader compilation failed"); - quit(-1); - } -} - -/* 3D data. Vertex range -0.5..0.5 in all axes. -* Z -0.5 is near, 0.5 is far. */ -const float _vertices[] = -{ - /* Front face. */ - /* Bottom left */ - -0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top right */ - -0.5, 0.5, -0.5, - 0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - /* Left face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - -0.5, -0.5, -0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, 0.5, 0.5, - -0.5, 0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, -0.5, - /* Top right */ - -0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - /* Right face */ - /* Bottom left */ - 0.5, 0.5, -0.5, - 0.5, -0.5, 0.5, - 0.5, -0.5, -0.5, - /* Top right */ - 0.5, 0.5, -0.5, - 0.5, 0.5, 0.5, - 0.5, -0.5, 0.5, - /* Back face */ - /* Bottom left */ - 0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - 0.5, -0.5, 0.5, - /* Top right */ - 0.5, 0.5, 0.5, - -0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - /* Bottom face */ - /* Bottom left */ - -0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, -}; - -const float _colors[] = -{ - /* Front face */ - /* Bottom left */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 1.0, /* blue */ - 0.0, 1.0, 0.0, /* green */ - /* Top right */ - 1.0, 0.0, 0.0, /* red */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 1.0, /* blue */ - /* Left face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 1.0, 0.0, /* green */ - /* Top face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 0.0, /* red */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 0.0, /* yellow */ - /* Right face */ - /* Bottom left */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - /* Top right */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 0.0, 1.0, /* magenta */ - /* Back face */ - /* Bottom left */ - 0.0, 0.0, 0.0, /* black */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - /* Top right */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - /* Bottom face */ - /* Bottom left */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 0.0, 1.0, /* magenta */ -}; - -const char* _shader_vert_src = -" attribute vec4 av4position; " -" attribute vec3 av3color; " -" uniform mat4 mvp; " -" varying vec3 vv3color; " -" void main() { " -" vv3color = av3color; " -" gl_Position = mvp * av4position; " -" } "; - -const char* _shader_frag_src = -" precision lowp float; " -" varying vec3 vv3color; " -" void main() { " -" gl_FragColor = vec4(vv3color, 1.0); " -" } "; - -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - -} shader_data; - -static void -Render(unsigned int width, unsigned int height, shader_data* data) -{ - float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; - - /* - * Do some rotation with Euler angles. It is not a fixed axis as - * quaterions would be, but the effect is cool. - */ - rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview); - rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - /* Pull the camera back from the cube */ - matrix_modelview[14] -= 2.5; - - perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective); - multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); - - data->angle_x += 3; - data->angle_y += 2; - data->angle_z += 1; - - if(data->angle_x >= 360) data->angle_x -= 360; - if(data->angle_x < 0) data->angle_x += 360; - if(data->angle_y >= 360) data->angle_y -= 360; - if(data->angle_y < 0) data->angle_y += 360; - if(data->angle_z >= 360) data->angle_z -= 360; - if(data->angle_z < 0) data->angle_z += 360; - - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - shader_data *datas, *data; - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], - SDLTest_CommonUsage(state)); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 2; - state->gl_minor_version = 0; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - return 0; - } - - context = SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_Log("Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GLES2 functions\n"); - quit(2); - return 0; - } - - - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - datas = SDL_calloc(state->num_windows, sizeof(shader_data)); - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - ctx.glViewport(0, 0, state->window_w, state->window_h); - - data = &datas[i]; - data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; - - /* Shader Initialization */ - process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); - process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); - - /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); - - /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); - - /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); - - /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); - - GL_CHECK(ctx.glUseProgram(data->shader_program)); - - /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); - - /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event) && !done) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - ctx.glViewport(0, 0, event.window.data1, event.window.data2); - /* Update window content */ - Render(event.window.data1, event.window.data2, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - if (!done) { - for (i = 0; i < state->num_windows; ++i) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(state->window_w, state->window_h, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - } - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES2 */ - -int -main(int argc, char *argv[]) -{ - SDL_Log("No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java index 616b1b0097..68359345cb 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java @@ -60,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", mFilesDirectory); SDLActivity.nativeSetEnv("ANDROID_APP_PATH", mFilesDirectory); SDLActivity.nativeSetEnv("PYTHONHOME", mFilesDirectory); - SDLActivity.nativeSetEnv("", mFilesDirectory + ":" + mFilesDirectory + "/lib"); + SDLActivity.nativeSetEnv("PYTHONPATH", mFilesDirectory + ":" + mFilesDirectory + "/lib"); // nativeSetEnv("ANDROID_ARGUMENT", getFilesDir()); @@ -93,7 +93,6 @@ protected String[] getLibraries() { "SDL2_image", "SDL2_mixer", "SDL2_ttf", - "python2.7", "main" }; } @@ -104,9 +103,25 @@ public void loadLibraries() { System.loadLibrary(lib); } - System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); - System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); - + try { + System.loadLibrary("python2.7"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load libpython2.7"); + } + + try { + System.loadLibrary("python3.5m"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load libpython3.5m"); + } + + try { + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load _io.so or unicodedata.so...but that's okay."); + } + try { // System.loadLibrary("ctypes"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); diff --git a/pythonforandroid/bootstraps/sdl2python3/__init__.py b/pythonforandroid/bootstraps/sdl2python3/__init__.py deleted file mode 100644 index ae693e79eb..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/__init__.py +++ /dev/null @@ -1,88 +0,0 @@ -from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main -from os.path import join, exists -from os import walk -import glob -import sh - -class SDL2Bootstrap(Bootstrap): - name = 'sdl2python3' - - recipe_depends = ['sdl2python3', 'python3'] - - can_be_chosen_automatically = False - - def run_distribute(self): - info_main('# Creating Android project from build and {} bootstrap'.format( - self.name)) - - info('This currently just copies the SDL2 build stuff straight from the build dir.') - shprint(sh.rm, '-rf', self.dist_dir) - shprint(sh.cp, '-r', self.build_dir, self.dist_dir) - with current_directory(self.dist_dir): - with open('local.properties', 'w') as fileh: - fileh.write('sdk.dir={}'.format(self.ctx.sdk_dir)) - - # AND: Hardcoding armeabi - naughty! - arch = ArchARM(self.ctx) - - with current_directory(self.dist_dir): - info('Copying python distribution') - - if not exists('private'): - shprint(sh.mkdir, 'private') - if not exists('assets'): - shprint(sh.mkdir, 'assets') - - hostpython = sh.Command(self.ctx.hostpython) - - # AND: The compileall doesn't work with python3, tries to import a wrong-arch lib - # shprint(hostpython, '-OO', '-m', 'compileall', join(self.ctx.build_dir, 'python-install')) - if not exists('python-install'): - shprint(sh.cp, '-a', join(self.ctx.build_dir, 'python-install'), '.') - - self.distribute_libs(arch, [self.ctx.libs_dir]) - self.distribute_aars(arch) - self.distribute_javaclasses(join(self.ctx.build_dir, 'java')) - - info('Filling private directory') - if not exists(join('private', 'lib')): - info('private/lib does not exist, making') - shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') - shprint(sh.mkdir, '-p', join('private', 'include', 'python3.4m')) - - # AND: Copylibs stuff should go here - if exists(join('libs', 'armeabi', 'libpymodules.so')): - shprint(sh.mv, join('libs', 'armeabi', 'libpymodules.so'), 'private/') - shprint(sh.cp, join('python-install', 'include' , 'python3.4m', 'pyconfig.h'), join('private', 'include', 'python3.4m/')) - - info('Removing some unwanted files') - shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.4m.so')) - shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.so')) - shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) - - with current_directory(join(self.dist_dir, 'private', 'lib', 'python3.4')): - # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) - removes = [] - for dirname, something, filens in walk('.'): - for filename in filens: - for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): - if filename.endswith(suffix): - removes.append(filename) - shprint(sh.rm, '-f', *removes) - - info('Deleting some other stuff not used on android') - # To quote the original distribute.sh, 'well...' - # shprint(sh.rm, '-rf', 'ctypes') - shprint(sh.rm, '-rf', 'lib2to3') - shprint(sh.rm, '-rf', 'idlelib') - for filename in glob.glob('config/libpython*.a'): - shprint(sh.rm, '-f', filename) - shprint(sh.rm, '-rf', 'config/python.o') - # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') - # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') - - - self.strip_libraries(arch) - super(SDL2Bootstrap, self).run_distribute() - -bootstrap = SDL2Bootstrap() diff --git a/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml b/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml deleted file mode 100644 index a3dfc7b224..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/ant.properties b/pythonforandroid/bootstraps/sdl2python3/build/ant.properties deleted file mode 100644 index b0971e891e..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/ant.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# -# This file must be checked into Version Control Systems, as it is -# integral to the build system of your project. - -# This file is only used by the Ant script. - -# You can use this to override default values such as -# 'source.dir' for the location of your java source folder and -# 'out.dir' for the location of your output folder. - -# You can also use it define how the release builds are signed by declaring -# the following properties: -# 'key.store' for the location of your keystore and -# 'key.alias' for the name of the key to use. -# The password will be asked during the build when you use the 'release' target. - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.properties b/pythonforandroid/bootstraps/sdl2python3/build/build.properties deleted file mode 100644 index edc7f23050..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# -# This file must be checked in Version Control Systems, as it is -# integral to the build system of your project. - -# This file is only used by the Ant script. - -# You can use this to override default values such as -# 'source.dir' for the location of your java source folder and -# 'out.dir' for the location of your output folder. - -# You can also use it define how the release builds are signed by declaring -# the following properties: -# 'key.store' for the location of your keystore and -# 'key.alias' for the name of the key to use. -# The password will be asked during the build when you use the 'release' target. - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.py b/pythonforandroid/bootstraps/sdl2python3/build/build.py deleted file mode 100755 index 654854049d..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python3 - -from __future__ import print_function - -from os.path import dirname, join, isfile, realpath, relpath, split -import os -import tarfile -import time -import subprocess -import shutil -from zipfile import ZipFile -import sys -import re - -from fnmatch import fnmatch - -import jinja2 - -if os.name == 'nt': - ANDROID = 'android.bat' - ANT = 'ant.bat' -else: - ANDROID = 'android' - ANT = 'ant' - -curdir = dirname(__file__) - -# Try to find a host version of Python that matches our ARM version. -PYTHON = join(curdir, 'python-install', 'bin', 'python.host') - -BLACKLIST_PATTERNS = [ - # code versionning - '^*.hg/*', - '^*.git/*', - '^*.bzr/*', - '^*.svn/*', - - # pyc/py - '*.pyc', - # '*.py', # AND: Need to fix this to add it back - - # temp files - '~', - '*.bak', - '*.swp', -] - -WHITELIST_PATTERNS = [] - -python_files = [] - - -environment = jinja2.Environment(loader=jinja2.FileSystemLoader( - join(curdir, 'templates'))) - -def render(template, dest, **kwargs): - '''Using jinja2, render `template` to the filename `dest`, supplying the - - keyword arguments as template parameters. - ''' - - template = environment.get_template(template) - text = template.render(**kwargs) - - f = open(dest, 'wb') - f.write(text.encode('utf-8')) - f.close() - - -def is_whitelist(name): - return match_filename(WHITELIST_PATTERNS, name) - - -def is_blacklist(name): - if is_whitelist(name): - return False - return match_filename(BLACKLIST_PATTERNS, name) - - -def match_filename(pattern_list, name): - for pattern in pattern_list: - if pattern.startswith('^'): - pattern = pattern[1:] - else: - pattern = '*/' + pattern - if fnmatch(name, pattern): - return True - - -def listfiles(d): - basedir = d - subdirlist = [] - for item in os.listdir(d): - fn = join(d, item) - if isfile(fn): - yield fn - else: - subdirlist.append(os.path.join(basedir, item)) - for subdir in subdirlist: - for fn in listfiles(subdir): - yield fn - -def make_python_zip(): - ''' - Search for all the python related files, and construct the pythonXX.zip - According to - # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html - site-packages, config and lib-dynload will be not included. - ''' - global python_files - d = realpath(join('private', 'lib', 'python3.4')) - - - def select(fn): - if is_blacklist(fn): - return False - fn = realpath(fn) - assert(fn.startswith(d)) - fn = fn[len(d):] - if (fn.startswith('/site-packages/') or - fn.startswith('/config/') or - fn.startswith('/lib-dynload/') or - fn.startswith('/libpymodules.so')): - return False - return fn - - # get a list of all python file - python_files = [x for x in listfiles(d) if select(x)] - - # create the final zipfile - zfn = join('private', 'lib', 'python34.zip') - zf = ZipFile(zfn, 'w') - - # put all the python files in it - for fn in python_files: - afn = fn[len(d):] - zf.write(fn, afn) - zf.close() - -def make_tar(tfn, source_dirs, ignore_path=[]): - ''' - Make a zip file `fn` from the contents of source_dis. - ''' - - # selector function - def select(fn): - rfn = realpath(fn) - for p in ignore_path: - if p.endswith('/'): - p = p[:-1] - if rfn.startswith(p): - return False - if rfn in python_files: - return False - return not is_blacklist(fn) - - # get the files and relpath file of all the directory we asked for - files = [] - for sd in source_dirs: - sd = realpath(sd) - compile_dir(sd) - files += [(x, relpath(realpath(x), sd)) for x in listfiles(sd) - if select(x)] - - # create tar.gz of thoses files - tf = tarfile.open(tfn, 'w:gz', format=tarfile.USTAR_FORMAT) - dirs = [] - for fn, afn in files: - print('%s: %s' % (tfn, fn)) - dn = dirname(afn) - if dn not in dirs: - # create every dirs first if not exist yet - d = '' - for component in split(dn): - d = join(d, component) - if d.startswith('/'): - d = d[1:] - if d == '' or d in dirs: - continue - dirs.append(d) - tinfo = tarfile.TarInfo(d) - tinfo.type = tarfile.DIRTYPE - tf.addfile(tinfo) - - # put the file - tf.add(fn, afn) - tf.close() - - -def compile_dir(dfn): - ''' - Compile *.py in directory `dfn` to *.pyo - ''' - - return # AND: Currently leaving out the compile to pyo step because it's somehow broken - # -OO = strip docstrings - subprocess.call([PYTHON, '-OO', '-m', 'compileall', '-f', dfn]) - - -def make_package(args): - url_scheme = 'kivy' - - # Figure out versions of the private and public data. - private_version = str(time.time()) - - # # Update the project to a recent version. - # try: - # subprocess.call([ANDROID, 'update', 'project', '-p', '.', '-t', - # 'android-{}'.format(args.sdk_version)]) - # except (OSError, IOError): - # print('An error occured while calling', ANDROID, 'update') - # print('Your PATH must include android tools.') - # sys.exit(-1) - - # Delete the old assets. - if os.path.exists('assets/public.mp3'): - os.unlink('assets/public.mp3') - - if os.path.exists('assets/private.mp3'): - os.unlink('assets/private.mp3') - - # In order to speedup import and initial depack, - # construct a python34.zip - make_python_zip() - - # Package up the private and public data. - # AND: Just private for now - if args.private: - make_tar('assets/private.mp3', ['private', args.private], args.ignore_path) - # else: - # make_tar('assets/private.mp3', ['private']) - - # if args.dir: - # make_tar('assets/public.mp3', [args.dir], args.ignore_path) - - - # # Build. - # try: - # for arg in args.command: - # subprocess.check_call([ANT, arg]) - # except (OSError, IOError): - # print 'An error occured while calling', ANT - # print 'Did you install ant on your system ?' - # sys.exit(-1) - - - # Prepare some variables for templating process - - default_icon = 'templates/kivy-icon.png' - shutil.copy(args.icon or default_icon, 'res/drawable/icon.png') - - versioned_name = (args.name.replace(' ', '').replace('\'', '') + - '-' + args.version) - - version_code = 0 - if not args.numeric_version: - for i in args.version.split('.'): - version_code *= 100 - version_code += int(i) - args.numeric_version = str(version_code) - - render( - 'AndroidManifest.xml.tmpl', - 'AndroidManifest.xml', - args=args, - ) - - render( - 'build.xml.tmpl', - 'build.xml', - args=args, - versioned_name=versioned_name) - - render( - 'strings.xml.tmpl', - 'res/values/strings.xml', - args=args) - - with open(join(dirname(__file__), 'res', - 'values', 'strings.xml')) as fileh: - lines = fileh.read() - - with open(join(dirname(__file__), 'res', - 'values', 'strings.xml'), 'w') as fileh: - fileh.write(re.sub(r'"private_version">[0-9\.]*<', - '"private_version">{}<'.format( - str(time.time())), lines)) - - -def parse_args(args=None): - import argparse - ap = argparse.ArgumentParser(description='''\ -Package a Python application for Android. - -For this to work, Java and Ant need to be in your path, as does the -tools directory of the Android SDK. -''') - - ap.add_argument('--private', dest='private', - help='the dir of user files', - required=True) - ap.add_argument('--package', dest='package', - help=('The name of the java package the project will be' - ' packaged under.'), - required=True) - ap.add_argument('--name', dest='name', - help=('The human-readable name of the project.'), - required=True) - ap.add_argument('--numeric-version', dest='numeric_version', - help=('The numeric version number of the project. If not ' - 'given, this is automatically computed from the ' - 'version.')) - ap.add_argument('--version', dest='version', - help=('The version number of the project. This should ' - 'consist of numbers and dots, and should have the ' - 'same number of groups of numbers as previous ' - 'versions.'), - required=True) - ap.add_argument('--orientation', dest='orientation', default='portrait', - help=('The orientation that the game will display in. ' - 'Usually one of "landscape", "portrait" or ' - '"sensor"')) - ap.add_argument('--icon', dest='icon', - help='A png file to use as the icon for the application.') - ap.add_argument('--permission', dest='permissions', action='append', - help='The permissions to give this app.') - - if args is None: - args = sys.argv[1:] - args = ap.parse_args(args) - args.ignore_path = [] - - if args.permissions is None: - args.permissions = [] - - make_package(args) - -if __name__ == "__main__": - - parse_args() diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.xml b/pythonforandroid/bootstraps/sdl2python3/build/build.xml deleted file mode 100644 index 9f19a077b1..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk deleted file mode 100644 index 5053e7d643..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk deleted file mode 100644 index 79b504d3f0..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk +++ /dev/null @@ -1,7 +0,0 @@ - -# Uncomment this if you're using STL in your project -# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information -# APP_STL := stlport_static - -# APP_ABI := armeabi armeabi-v7a x86 -APP_ABI := armeabi diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk deleted file mode 100644 index 76f0eee24f..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := main - -SDL_PATH := ../SDL - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include - -# Add your application source files here... -LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ - start.c - -LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../python-install/include/python3.4m - -LOCAL_SHARED_LIBRARIES := SDL2 - -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lpython3.4m - -LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) - -include $(BUILD_SHARED_LIBRARY) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk deleted file mode 100644 index faed669c0e..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk +++ /dev/null @@ -1,12 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := main - -LOCAL_SRC_FILES := YourSourceHere.c - -LOCAL_STATIC_LIBRARIES := SDL2_static - -include $(BUILD_SHARED_LIBRARY) -$(call import-module,SDL)LOCAL_PATH := $(call my-dir) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c deleted file mode 100644 index b67bf6894f..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c +++ /dev/null @@ -1,218 +0,0 @@ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#else - -#include -#include -#include -#include - -#include "SDL.h" - -/* #include */ - -#include "android/log.h" - -/* #include "jniwrapperstuff.h" */ - - -/* AND: I don't know why this include is needed! */ -#include "SDL_opengles2.h" - -#define LOG(x) __android_log_write(ANDROID_LOG_INFO, "python", (x)) - -static PyObject *androidembed_log(PyObject *self, PyObject *args) { - char *logstr = NULL; - if (!PyArg_ParseTuple(args, "s", &logstr)) { - return NULL; - } - LOG(logstr); - Py_RETURN_NONE; -} - -static PyMethodDef AndroidEmbedMethods[] = { - {"log", androidembed_log, METH_VARARGS, - "Log on android platform"}, - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef androidembed = - { - PyModuleDef_HEAD_INIT, - "androidembed", - "", - -1, - AndroidEmbedMethods - }; - -PyMODINIT_FUNC initandroidembed(void) { - return PyModule_Create(&androidembed); - /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ -} - -int file_exists(const char * filename) -{ - FILE *file; - if (file = fopen(filename, "r")) { - fclose(file); - return 1; - } - return 0; -} - -/* int main(int argc, char **argv) { */ -int main(int argc, char *argv[]) { - - char *env_argument = NULL; - int ret = 0; - FILE *fd; - - /* AND: Several filepaths are hardcoded here, these must be made - configurable */ - /* AND: P4A uses env vars...not sure what's best */ - LOG("Initialize Python for Android"); - /* env_argument = "/data/data/org.kivy.android/files"; */ - env_argument = getenv("ANDROID_ARGUMENT"); - /* setenv("ANDROID_APP_PATH", env_argument, 1); */ - - /* setenv("ANDROID_ARGUMENT", env_argument, 1); */ - /* setenv("ANDROID_PRIVATE", env_argument, 1); */ - /* setenv("ANDROID_APP_PATH", env_argument, 1); */ - /* setenv("PYTHONHOME", env_argument, 1); */ - /* setenv("PYTHONPATH", "/data/data/org.kivy.android/files:/data/data/org.kivy.android/files/lib", 1); */ - - /* LOG("AND: Set env vars"); */ - /* LOG(argv[0]); */ - /* LOG("AND: That was argv 0"); */ - //setenv("PYTHONVERBOSE", "2", 1); - - /* Py_SetProgramName(argv[0]); /\* Disabled due to problem passing wchar_ *\/ */ - Py_SetProgramName("testsetprogramname"); - LOG("Set program name"); - Py_Initialize(); - /* PySys_SetArgv(argc, argv); */ /* Disabled due to problem passing wchar_ */ - - LOG("Initialized python"); - - /* ensure threads will work. - */ - PyEval_InitThreads(); - - LOG("AND: Init threads"); - - /* our logging module for android - */ - initandroidembed(); - - LOG("AND: Init embed"); - - /* inject our bootstrap code to redirect python stdin/stdout - * replace sys.path with our path - */ - PyRun_SimpleString( - "import sys, posix\n" \ - "private = posix.environ['ANDROID_PRIVATE']\n" \ - "argument = posix.environ['ANDROID_ARGUMENT']\n" \ - "sys.path[:] = [ \n" \ - " private + '/lib/python27.zip', \n" \ - " private + '/lib/python2.7/', \n" \ - " private + '/lib/python2.7/lib-dynload/', \n" \ - " private + '/lib/python2.7/site-packages/', \n" \ - " argument ]\n" \ - "import androidembed\n" \ - "class LogFile(object):\n" \ - " def __init__(self):\n" \ - " self.buffer = ''\n" \ - " def write(self, s):\n" \ - " s = self.buffer + s\n" \ - " lines = s.split(\"\\n\")\n" \ - " for l in lines[:-1]:\n" \ - " androidembed.log(l)\n" \ - " self.buffer = lines[-1]\n" \ - " def flush(self):\n" \ - " return\n" \ - "sys.stdout = sys.stderr = LogFile()\n" \ - "import site; print site.getsitepackages()\n"\ - "print 'Android path', sys.path\n" \ - "print 'Android kivy bootstrap done. __name__ is', __name__"); - - LOG("AND: Ran string"); - /* run it ! - */ - LOG("Run user program, change dir and execute main.py"); - chdir(env_argument); - - /* search the initial main.py - */ - char *main_py = "main.pyo"; - if ( file_exists(main_py) == 0 ) { - if ( file_exists("main.py") ) - main_py = "main.py"; - else - main_py = NULL; - } - - if ( main_py == NULL ) { - LOG("No main.pyo / main.py found."); - return -1; - } - - fd = fopen(main_py, "r"); - if ( fd == NULL ) { - LOG("Open the main.py(o) failed"); - return -1; - } - - /* run python ! - */ - ret = PyRun_SimpleFile(fd, main_py); - - if (PyErr_Occurred() != NULL) { - ret = 1; - PyErr_Print(); /* This exits with the right code if SystemExit. */ - PyObject *f = PySys_GetObject("stdout"); - if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ - PyErr_Clear(); - } - - /* close everything - */ - Py_Finalize(); - fclose(fd); - - LOG("Python for android ended."); - return ret; -} - -/* JNIEXPORT void JNICALL JAVA_EXPORT_NAME(PythonService_nativeStart) ( JNIEnv* env, jobject thiz, */ -/* jstring j_android_private, */ -/* jstring j_android_argument, */ -/* jstring j_python_home, */ -/* jstring j_python_path, */ -/* jstring j_arg ) */ -/* { */ -/* jboolean iscopy; */ -/* const char *android_private = (*env)->GetStringUTFChars(env, j_android_private, &iscopy); */ -/* const char *android_argument = (*env)->GetStringUTFChars(env, j_android_argument, &iscopy); */ -/* const char *python_home = (*env)->GetStringUTFChars(env, j_python_home, &iscopy); */ -/* const char *python_path = (*env)->GetStringUTFChars(env, j_python_path, &iscopy); */ -/* const char *arg = (*env)->GetStringUTFChars(env, j_arg, &iscopy); */ - -/* setenv("ANDROID_PRIVATE", android_private, 1); */ -/* setenv("ANDROID_ARGUMENT", android_argument, 1); */ -/* setenv("PYTHONOPTIMIZE", "2", 1); */ -/* setenv("PYTHONHOME", python_home, 1); */ -/* setenv("PYTHONPATH", python_path, 1); */ -/* setenv("PYTHON_SERVICE_ARGUMENT", arg, 1); */ - -/* char *argv[] = { "service" }; */ -/* /\* ANDROID_ARGUMENT points to service subdir, */ -/* * so main() will run main.py from this dir */ -/* *\/ */ -/* main(1, argv); */ -/* } */ - -#endif diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c deleted file mode 100644 index ef9f38d607..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - Copyright (r) 1997-2014 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES2 -#endif - -#ifdef HAVE_OPENGLES2 - -#include "SDL_opengles2.h" - -typedef struct GLES2_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC -} GLES2_Context; - - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; -static GLES2_Context ctx; - -static int LoadContext(GLES2_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* _SDL_NOGETPROCADDR_ */ - -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC - return 0; -} - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -#define GL_CHECK(x) \ - x; \ - { \ - GLenum glError = ctx.glGetError(); \ - if(glError != GL_NO_ERROR) { \ - SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ - quit(1); \ - } \ - } - -/* - * Simulates desktop's glRotatef. The matrix is returned in column-major - * order. - */ -static void -rotate_matrix(double angle, double x, double y, double z, float *r) -{ - double radians, c, s, c1, u[3], length; - int i, j; - - radians = (angle * M_PI) / 180.0; - - c = cos(radians); - s = sin(radians); - - c1 = 1.0 - cos(radians); - - length = sqrt(x * x + y * y + z * z); - - u[0] = x / length; - u[1] = y / length; - u[2] = z / length; - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[15] = 1.0; - - for (i = 0; i < 3; i++) { - r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; - r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; - } - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0); - } - } -} - -/* - * Simulates gluPerspectiveMatrix - */ -static void -perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r) -{ - int i; - double f; - - f = 1.0/tan(fovy * 0.5); - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[0] = f / aspect; - r[5] = f; - r[10] = (znear + zfar) / (znear - zfar); - r[11] = -1.0; - r[14] = (2.0 * znear * zfar) / (znear - zfar); - r[15] = 0.0; -} - -/* - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column - * major. In-place multiplication is supported. - */ -static void -multiply_matrix(float *lhs, float *rhs, float *r) -{ - int i, j, k; - float tmp[16]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - tmp[j * 4 + i] = 0.0; - - for (k = 0; k < 4; k++) { - tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; - } - } - } - - for (i = 0; i < 16; i++) { - r[i] = tmp[i]; - } -} - -/* - * Create shader, load in source, compile, dump debug as necessary. - * - * shader: Pointer to return created shader ID. - * source: Passed-in shader source code. - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. - */ -void -process_shader(GLuint *shader, const char * source, GLint shader_type) -{ - GLint status = GL_FALSE; - const char *shaders[1] = { NULL }; - - /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); - - shaders[0] = source; - - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); - - /* Clean up shader source. */ - shaders[0] = NULL; - - /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); - - // Dump debug info (source and log) if compilation failed. - if(status != GL_TRUE) { - SDL_Log("Shader compilation failed"); - quit(-1); - } -} - -/* 3D data. Vertex range -0.5..0.5 in all axes. -* Z -0.5 is near, 0.5 is far. */ -const float _vertices[] = -{ - /* Front face. */ - /* Bottom left */ - -0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top right */ - -0.5, 0.5, -0.5, - 0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - /* Left face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - -0.5, -0.5, -0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, 0.5, 0.5, - -0.5, 0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, -0.5, - /* Top right */ - -0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - /* Right face */ - /* Bottom left */ - 0.5, 0.5, -0.5, - 0.5, -0.5, 0.5, - 0.5, -0.5, -0.5, - /* Top right */ - 0.5, 0.5, -0.5, - 0.5, 0.5, 0.5, - 0.5, -0.5, 0.5, - /* Back face */ - /* Bottom left */ - 0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - 0.5, -0.5, 0.5, - /* Top right */ - 0.5, 0.5, 0.5, - -0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - /* Bottom face */ - /* Bottom left */ - -0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, -}; - -const float _colors[] = -{ - /* Front face */ - /* Bottom left */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 1.0, /* blue */ - 0.0, 1.0, 0.0, /* green */ - /* Top right */ - 1.0, 0.0, 0.0, /* red */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 1.0, /* blue */ - /* Left face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 1.0, 0.0, /* green */ - /* Top face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 0.0, /* red */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 0.0, /* yellow */ - /* Right face */ - /* Bottom left */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - /* Top right */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 0.0, 1.0, /* magenta */ - /* Back face */ - /* Bottom left */ - 0.0, 0.0, 0.0, /* black */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - /* Top right */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - /* Bottom face */ - /* Bottom left */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 0.0, 1.0, /* magenta */ -}; - -const char* _shader_vert_src = -" attribute vec4 av4position; " -" attribute vec3 av3color; " -" uniform mat4 mvp; " -" varying vec3 vv3color; " -" void main() { " -" vv3color = av3color; " -" gl_Position = mvp * av4position; " -" } "; - -const char* _shader_frag_src = -" precision lowp float; " -" varying vec3 vv3color; " -" void main() { " -" gl_FragColor = vec4(vv3color, 1.0); " -" } "; - -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - -} shader_data; - -static void -Render(unsigned int width, unsigned int height, shader_data* data) -{ - float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; - - /* - * Do some rotation with Euler angles. It is not a fixed axis as - * quaterions would be, but the effect is cool. - */ - rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview); - rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - /* Pull the camera back from the cube */ - matrix_modelview[14] -= 2.5; - - perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective); - multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); - - data->angle_x += 3; - data->angle_y += 2; - data->angle_z += 1; - - if(data->angle_x >= 360) data->angle_x -= 360; - if(data->angle_x < 0) data->angle_x += 360; - if(data->angle_y >= 360) data->angle_y -= 360; - if(data->angle_y < 0) data->angle_y += 360; - if(data->angle_z >= 360) data->angle_z -= 360; - if(data->angle_z < 0) data->angle_z += 360; - - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - shader_data *datas, *data; - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], - SDLTest_CommonUsage(state)); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 2; - state->gl_minor_version = 0; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - return 0; - } - - context = SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_Log("Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GLES2 functions\n"); - quit(2); - return 0; - } - - - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - datas = SDL_calloc(state->num_windows, sizeof(shader_data)); - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - ctx.glViewport(0, 0, state->window_w, state->window_h); - - data = &datas[i]; - data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; - - /* Shader Initialization */ - process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); - process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); - - /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); - - /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); - - /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); - - /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); - - GL_CHECK(ctx.glUseProgram(data->shader_program)); - - /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); - - /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event) && !done) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - ctx.glViewport(0, 0, event.window.data1, event.window.data2); - /* Update window content */ - Render(event.window.data1, event.window.data2, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - if (!done) { - for (i = 0; i < state->num_windows; ++i) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(state->window_w, state->window_h, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - } - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES2 */ - -int -main(int argc, char *argv[]) -{ - SDL_Log("No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt b/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt deleted file mode 100644 index f2fe1559a2..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index d50bdaae06..0000000000 Binary files a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 0a299eb3cc..0000000000 Binary files a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xhdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index a336ad5c2b..0000000000 Binary files a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index d423dac262..0000000000 Binary files a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/.gitkeep b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png deleted file mode 100644 index 59a00ba6ff..0000000000 Binary files a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png and /dev/null differ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml b/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml deleted file mode 100644 index 123c4b6eac..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml b/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml deleted file mode 100644 index daebceb9d5..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - SDL App - 0.1 - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java deleted file mode 100755 index dd10624eab..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -/** - * @author Kamran Zafar - * - */ -public class Octal { - - /** - * Parse an octal string from a header buffer. This is used for the file - * permission mode value. - * - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The long value of the octal string. - */ - public static long parseOctal(byte[] header, int offset, int length) { - long result = 0; - boolean stillPadding = true; - - int end = offset + length; - for (int i = offset; i < end; ++i) { - if (header[i] == 0) - break; - - if (header[i] == (byte) ' ' || header[i] == '0') { - if (stillPadding) - continue; - - if (header[i] == (byte) ' ') - break; - } - - stillPadding = false; - - result = ( result << 3 ) + ( header[i] - '0' ); - } - - return result; - } - - /** - * Parse an octal integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The integer value of the octal bytes. - */ - public static int getOctalBytes(long value, byte[] buf, int offset, int length) { - int idx = length - 1; - - buf[offset + idx] = 0; - --idx; - buf[offset + idx] = (byte) ' '; - --idx; - - if (value == 0) { - buf[offset + idx] = (byte) '0'; - --idx; - } else { - for (long val = value; idx >= 0 && val > 0; --idx) { - buf[offset + idx] = (byte) ( (byte) '0' + (byte) ( val & 7 ) ); - val = val >> 3; - } - } - - for (; idx >= 0; --idx) { - buf[offset + idx] = (byte) ' '; - } - - return offset + length; - } - - /** - * Parse the checksum octal integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The integer value of the entry's checksum. - */ - public static int getCheckSumOctalBytes(long value, byte[] buf, int offset, int length) { - getOctalBytes( value, buf, offset, length ); - buf[offset + length - 1] = (byte) ' '; - buf[offset + length - 2] = 0; - return offset + length; - } - - /** - * Parse an octal long integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The long value of the octal bytes. - */ - public static int getLongOctalBytes(long value, byte[] buf, int offset, int length) { - byte[] temp = new byte[length + 1]; - getOctalBytes( value, temp, 0, length + 1 ); - System.arraycopy( temp, 0, buf, offset, length ); - return offset + length; - } - -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java deleted file mode 100755 index 4611e20eaa..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -/** - * @author Kamran Zafar - * - */ -public class TarConstants { - public static final int EOF_BLOCK = 1024; - public static final int DATA_BLOCK = 512; - public static final int HEADER_BLOCK = 512; -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java deleted file mode 100755 index fe01db463a..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java +++ /dev/null @@ -1,284 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; -import java.util.Date; - -/** - * @author Kamran Zafar - * - */ -public class TarEntry { - protected File file; - protected TarHeader header; - - private TarEntry() { - this.file = null; - header = new TarHeader(); - } - - public TarEntry(File file, String entryName) { - this(); - this.file = file; - this.extractTarHeader(entryName); - } - - public TarEntry(byte[] headerBuf) { - this(); - this.parseTarHeader(headerBuf); - } - - /** - * Constructor to create an entry from an existing TarHeader object. - * - * This method is useful to add new entries programmatically (e.g. for - * adding files or directories that do not exist in the file system). - * - * @param header - * - */ - public TarEntry(TarHeader header) { - this.file = null; - this.header = header; - } - - public boolean equals(TarEntry it) { - return header.name.toString().equals(it.header.name.toString()); - } - - public boolean isDescendent(TarEntry desc) { - return desc.header.name.toString().startsWith(header.name.toString()); - } - - public TarHeader getHeader() { - return header; - } - - public String getName() { - String name = header.name.toString(); - if (header.namePrefix != null && !header.namePrefix.toString().equals("")) { - name = header.namePrefix.toString() + "/" + name; - } - - return name; - } - - public void setName(String name) { - header.name = new StringBuffer(name); - } - - public int getUserId() { - return header.userId; - } - - public void setUserId(int userId) { - header.userId = userId; - } - - public int getGroupId() { - return header.groupId; - } - - public void setGroupId(int groupId) { - header.groupId = groupId; - } - - public String getUserName() { - return header.userName.toString(); - } - - public void setUserName(String userName) { - header.userName = new StringBuffer(userName); - } - - public String getGroupName() { - return header.groupName.toString(); - } - - public void setGroupName(String groupName) { - header.groupName = new StringBuffer(groupName); - } - - public void setIds(int userId, int groupId) { - this.setUserId(userId); - this.setGroupId(groupId); - } - - public void setModTime(long time) { - header.modTime = time / 1000; - } - - public void setModTime(Date time) { - header.modTime = time.getTime() / 1000; - } - - public Date getModTime() { - return new Date(header.modTime * 1000); - } - - public File getFile() { - return this.file; - } - - public long getSize() { - return header.size; - } - - public void setSize(long size) { - header.size = size; - } - - /** - * Checks if the org.kamrazafar.jtar entry is a directory - * - * @return - */ - public boolean isDirectory() { - if (this.file != null) - return this.file.isDirectory(); - - if (header != null) { - if (header.linkFlag == TarHeader.LF_DIR) - return true; - - if (header.name.toString().endsWith("/")) - return true; - } - - return false; - } - - /** - * Extract header from File - * - * @param entryName - */ - public void extractTarHeader(String entryName) { - header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory()); - } - - /** - * Calculate checksum - * - * @param buf - * @return - */ - public long computeCheckSum(byte[] buf) { - long sum = 0; - - for (int i = 0; i < buf.length; ++i) { - sum += 255 & buf[i]; - } - - return sum; - } - - /** - * Writes the header to the byte buffer - * - * @param outbuf - */ - public void writeEntryHeader(byte[] outbuf) { - int offset = 0; - - offset = TarHeader.getNameBytes(header.name, outbuf, offset, TarHeader.NAMELEN); - offset = Octal.getOctalBytes(header.mode, outbuf, offset, TarHeader.MODELEN); - offset = Octal.getOctalBytes(header.userId, outbuf, offset, TarHeader.UIDLEN); - offset = Octal.getOctalBytes(header.groupId, outbuf, offset, TarHeader.GIDLEN); - - long size = header.size; - - offset = Octal.getLongOctalBytes(size, outbuf, offset, TarHeader.SIZELEN); - offset = Octal.getLongOctalBytes(header.modTime, outbuf, offset, TarHeader.MODTIMELEN); - - int csOffset = offset; - for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) - outbuf[offset++] = (byte) ' '; - - outbuf[offset++] = header.linkFlag; - - offset = TarHeader.getNameBytes(header.linkName, outbuf, offset, TarHeader.NAMELEN); - offset = TarHeader.getNameBytes(header.magic, outbuf, offset, TarHeader.USTAR_MAGICLEN); - offset = TarHeader.getNameBytes(header.userName, outbuf, offset, TarHeader.USTAR_USER_NAMELEN); - offset = TarHeader.getNameBytes(header.groupName, outbuf, offset, TarHeader.USTAR_GROUP_NAMELEN); - offset = Octal.getOctalBytes(header.devMajor, outbuf, offset, TarHeader.USTAR_DEVLEN); - offset = Octal.getOctalBytes(header.devMinor, outbuf, offset, TarHeader.USTAR_DEVLEN); - offset = TarHeader.getNameBytes(header.namePrefix, outbuf, offset, TarHeader.USTAR_FILENAME_PREFIX); - - for (; offset < outbuf.length;) - outbuf[offset++] = 0; - - long checkSum = this.computeCheckSum(outbuf); - - Octal.getCheckSumOctalBytes(checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN); - } - - /** - * Parses the tar header to the byte buffer - * - * @param header - * @param bh - */ - public void parseTarHeader(byte[] bh) { - int offset = 0; - - header.name = TarHeader.parseName(bh, offset, TarHeader.NAMELEN); - offset += TarHeader.NAMELEN; - - header.mode = (int) Octal.parseOctal(bh, offset, TarHeader.MODELEN); - offset += TarHeader.MODELEN; - - header.userId = (int) Octal.parseOctal(bh, offset, TarHeader.UIDLEN); - offset += TarHeader.UIDLEN; - - header.groupId = (int) Octal.parseOctal(bh, offset, TarHeader.GIDLEN); - offset += TarHeader.GIDLEN; - - header.size = Octal.parseOctal(bh, offset, TarHeader.SIZELEN); - offset += TarHeader.SIZELEN; - - header.modTime = Octal.parseOctal(bh, offset, TarHeader.MODTIMELEN); - offset += TarHeader.MODTIMELEN; - - header.checkSum = (int) Octal.parseOctal(bh, offset, TarHeader.CHKSUMLEN); - offset += TarHeader.CHKSUMLEN; - - header.linkFlag = bh[offset++]; - - header.linkName = TarHeader.parseName(bh, offset, TarHeader.NAMELEN); - offset += TarHeader.NAMELEN; - - header.magic = TarHeader.parseName(bh, offset, TarHeader.USTAR_MAGICLEN); - offset += TarHeader.USTAR_MAGICLEN; - - header.userName = TarHeader.parseName(bh, offset, TarHeader.USTAR_USER_NAMELEN); - offset += TarHeader.USTAR_USER_NAMELEN; - - header.groupName = TarHeader.parseName(bh, offset, TarHeader.USTAR_GROUP_NAMELEN); - offset += TarHeader.USTAR_GROUP_NAMELEN; - - header.devMajor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN); - offset += TarHeader.USTAR_DEVLEN; - - header.devMinor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN); - offset += TarHeader.USTAR_DEVLEN; - - header.namePrefix = TarHeader.parseName(bh, offset, TarHeader.USTAR_FILENAME_PREFIX); - } -} \ No newline at end of file diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java deleted file mode 100755 index b9d3a86bef..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; - -/** - * Header - * - *
- * Offset  Size     Field
- * 0       100      File name
- * 100     8        File mode
- * 108     8        Owner's numeric user ID
- * 116     8        Group's numeric user ID
- * 124     12       File size in bytes
- * 136     12       Last modification time in numeric Unix time format
- * 148     8        Checksum for header block
- * 156     1        Link indicator (file type)
- * 157     100      Name of linked file
- * 
- * - * - * File Types - * - *
- * Value        Meaning
- * '0'          Normal file
- * (ASCII NUL)  Normal file (now obsolete)
- * '1'          Hard link
- * '2'          Symbolic link
- * '3'          Character special
- * '4'          Block special
- * '5'          Directory
- * '6'          FIFO
- * '7'          Contigous
- * 
- * - * - * - * Ustar header - * - *
- * Offset  Size    Field
- * 257     6       UStar indicator "ustar"
- * 263     2       UStar version "00"
- * 265     32      Owner user name
- * 297     32      Owner group name
- * 329     8       Device major number
- * 337     8       Device minor number
- * 345     155     Filename prefix
- * 
- */ - -public class TarHeader { - - /* - * Header - */ - public static final int NAMELEN = 100; - public static final int MODELEN = 8; - public static final int UIDLEN = 8; - public static final int GIDLEN = 8; - public static final int SIZELEN = 12; - public static final int MODTIMELEN = 12; - public static final int CHKSUMLEN = 8; - public static final byte LF_OLDNORM = 0; - - /* - * File Types - */ - public static final byte LF_NORMAL = (byte) '0'; - public static final byte LF_LINK = (byte) '1'; - public static final byte LF_SYMLINK = (byte) '2'; - public static final byte LF_CHR = (byte) '3'; - public static final byte LF_BLK = (byte) '4'; - public static final byte LF_DIR = (byte) '5'; - public static final byte LF_FIFO = (byte) '6'; - public static final byte LF_CONTIG = (byte) '7'; - - /* - * Ustar header - */ - - public static final String USTAR_MAGIC = "ustar"; // POSIX - - public static final int USTAR_MAGICLEN = 8; - public static final int USTAR_USER_NAMELEN = 32; - public static final int USTAR_GROUP_NAMELEN = 32; - public static final int USTAR_DEVLEN = 8; - public static final int USTAR_FILENAME_PREFIX = 155; - - // Header values - public StringBuffer name; - public int mode; - public int userId; - public int groupId; - public long size; - public long modTime; - public int checkSum; - public byte linkFlag; - public StringBuffer linkName; - public StringBuffer magic; // ustar indicator and version - public StringBuffer userName; - public StringBuffer groupName; - public int devMajor; - public int devMinor; - public StringBuffer namePrefix; - - public TarHeader() { - this.magic = new StringBuffer(TarHeader.USTAR_MAGIC); - - this.name = new StringBuffer(); - this.linkName = new StringBuffer(); - - String user = System.getProperty("user.name", ""); - - if (user.length() > 31) - user = user.substring(0, 31); - - this.userId = 0; - this.groupId = 0; - this.userName = new StringBuffer(user); - this.groupName = new StringBuffer(""); - this.namePrefix = new StringBuffer(); - } - - /** - * Parse an entry name from a header buffer. - * - * @param name - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The header's entry name. - */ - public static StringBuffer parseName(byte[] header, int offset, int length) { - StringBuffer result = new StringBuffer(length); - - int end = offset + length; - for (int i = offset; i < end; ++i) { - if (header[i] == 0) - break; - result.append((char) header[i]); - } - - return result; - } - - /** - * Determine the number of bytes in an entry name. - * - * @param name - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The number of bytes in a header's entry name. - */ - public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) { - int i; - - for (i = 0; i < length && i < name.length(); ++i) { - buf[offset + i] = (byte) name.charAt(i); - } - - for (; i < length; ++i) { - buf[offset + i] = 0; - } - - return offset + length; - } - - /** - * Creates a new header for a file/directory entry. - * - * - * @param name - * File name - * @param size - * File size in bytes - * @param modTime - * Last modification time in numeric Unix time format - * @param dir - * Is directory - * - * @return - */ - public static TarHeader createHeader(String entryName, long size, long modTime, boolean dir) { - String name = entryName; - name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/'); - - TarHeader header = new TarHeader(); - header.linkName = new StringBuffer(""); - - if (name.length() > 100) { - header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/'))); - header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1)); - } else { - header.name = new StringBuffer(name); - } - - if (dir) { - header.mode = 040755; - header.linkFlag = TarHeader.LF_DIR; - if (header.name.charAt(header.name.length() - 1) != '/') { - header.name.append("/"); - } - header.size = 0; - } else { - header.mode = 0100644; - header.linkFlag = TarHeader.LF_NORMAL; - header.size = size; - } - - header.modTime = modTime; - header.checkSum = 0; - header.devMajor = 0; - header.devMinor = 0; - - return header; - } -} \ No newline at end of file diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java deleted file mode 100755 index ec50a1b688..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Kamran Zafar - * - */ -public class TarInputStream extends FilterInputStream { - - private static final int SKIP_BUFFER_SIZE = 2048; - private TarEntry currentEntry; - private long currentFileSize; - private long bytesRead; - private boolean defaultSkip = false; - - public TarInputStream(InputStream in) { - super(in); - currentFileSize = 0; - bytesRead = 0; - } - - @Override - public boolean markSupported() { - return false; - } - - /** - * Not supported - * - */ - @Override - public synchronized void mark(int readlimit) { - } - - /** - * Not supported - * - */ - @Override - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - /** - * Read a byte - * - * @see java.io.FilterInputStream#read() - */ - @Override - public int read() throws IOException { - byte[] buf = new byte[1]; - - int res = this.read(buf, 0, 1); - - if (res != -1) { - return 0xFF & buf[0]; - } - - return res; - } - - /** - * Checks if the bytes being read exceed the entry size and adjusts the byte - * array length. Updates the byte counters - * - * - * @see java.io.FilterInputStream#read(byte[], int, int) - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (currentEntry != null) { - if (currentFileSize == currentEntry.getSize()) { - return -1; - } else if ((currentEntry.getSize() - currentFileSize) < len) { - len = (int) (currentEntry.getSize() - currentFileSize); - } - } - - int br = super.read(b, off, len); - - if (br != -1) { - if (currentEntry != null) { - currentFileSize += br; - } - - bytesRead += br; - } - - return br; - } - - /** - * Returns the next entry in the tar file - * - * @return TarEntry - * @throws IOException - */ - public TarEntry getNextEntry() throws IOException { - closeCurrentEntry(); - - byte[] header = new byte[TarConstants.HEADER_BLOCK]; - byte[] theader = new byte[TarConstants.HEADER_BLOCK]; - int tr = 0; - - // Read full header - while (tr < TarConstants.HEADER_BLOCK) { - int res = read(theader, 0, TarConstants.HEADER_BLOCK - tr); - - if (res < 0) { - break; - } - - System.arraycopy(theader, 0, header, tr, res); - tr += res; - } - - // Check if record is null - boolean eof = true; - for (byte b : header) { - if (b != 0) { - eof = false; - break; - } - } - - if (!eof) { - currentEntry = new TarEntry(header); - } - - return currentEntry; - } - - /** - * Returns the current offset (in bytes) from the beginning of the stream. - * This can be used to find out at which point in a tar file an entry's content begins, for instance. - */ - public long getCurrentOffset() { - return bytesRead; - } - - /** - * Closes the current tar entry - * - * @throws IOException - */ - protected void closeCurrentEntry() throws IOException { - if (currentEntry != null) { - if (currentEntry.getSize() > currentFileSize) { - // Not fully read, skip rest of the bytes - long bs = 0; - while (bs < currentEntry.getSize() - currentFileSize) { - long res = skip(currentEntry.getSize() - currentFileSize - bs); - - if (res == 0 && currentEntry.getSize() - currentFileSize > 0) { - // I suspect file corruption - throw new IOException("Possible tar file corruption"); - } - - bs += res; - } - } - - currentEntry = null; - currentFileSize = 0L; - skipPad(); - } - } - - /** - * Skips the pad at the end of each tar entry file content - * - * @throws IOException - */ - protected void skipPad() throws IOException { - if (bytesRead > 0) { - int extra = (int) (bytesRead % TarConstants.DATA_BLOCK); - - if (extra > 0) { - long bs = 0; - while (bs < TarConstants.DATA_BLOCK - extra) { - long res = skip(TarConstants.DATA_BLOCK - extra - bs); - bs += res; - } - } - } - } - - /** - * Skips 'n' bytes on the InputStream
- * Overrides default implementation of skip - * - */ - @Override - public long skip(long n) throws IOException { - if (defaultSkip) { - // use skip method of parent stream - // may not work if skip not implemented by parent - long bs = super.skip(n); - bytesRead += bs; - - return bs; - } - - if (n <= 0) { - return 0; - } - - long left = n; - byte[] sBuff = new byte[SKIP_BUFFER_SIZE]; - - while (left > 0) { - int res = read(sBuff, 0, (int) (left < SKIP_BUFFER_SIZE ? left : SKIP_BUFFER_SIZE)); - if (res < 0) { - break; - } - left -= res; - } - - return n - left; - } - - public boolean isDefaultSkip() { - return defaultSkip; - } - - public void setDefaultSkip(boolean defaultSkip) { - this.defaultSkip = defaultSkip; - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java deleted file mode 100755 index ffdfe87564..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; - -/** - * @author Kamran Zafar - * - */ -public class TarOutputStream extends OutputStream { - private final OutputStream out; - private long bytesWritten; - private long currentFileSize; - private TarEntry currentEntry; - - public TarOutputStream(OutputStream out) { - this.out = out; - bytesWritten = 0; - currentFileSize = 0; - } - - public TarOutputStream(final File fout) throws FileNotFoundException { - this.out = new BufferedOutputStream(new FileOutputStream(fout)); - bytesWritten = 0; - currentFileSize = 0; - } - - /** - * Opens a file for writing. - */ - public TarOutputStream(final File fout, final boolean append) throws IOException { - @SuppressWarnings("resource") - RandomAccessFile raf = new RandomAccessFile(fout, "rw"); - final long fileSize = fout.length(); - if (append && fileSize > TarConstants.EOF_BLOCK) { - raf.seek(fileSize - TarConstants.EOF_BLOCK); - } - out = new BufferedOutputStream(new FileOutputStream(raf.getFD())); - } - - /** - * Appends the EOF record and closes the stream - * - * @see java.io.FilterOutputStream#close() - */ - @Override - public void close() throws IOException { - closeCurrentEntry(); - write( new byte[TarConstants.EOF_BLOCK] ); - out.close(); - } - /** - * Writes a byte to the stream and updates byte counters - * - * @see java.io.FilterOutputStream#write(int) - */ - @Override - public void write(int b) throws IOException { - out.write( b ); - bytesWritten += 1; - - if (currentEntry != null) { - currentFileSize += 1; - } - } - - /** - * Checks if the bytes being written exceed the current entry size. - * - * @see java.io.FilterOutputStream#write(byte[], int, int) - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (currentEntry != null && !currentEntry.isDirectory()) { - if (currentEntry.getSize() < currentFileSize + len) { - throw new IOException( "The current entry[" + currentEntry.getName() + "] size[" - + currentEntry.getSize() + "] is smaller than the bytes[" + ( currentFileSize + len ) - + "] being written." ); - } - } - - out.write( b, off, len ); - - bytesWritten += len; - - if (currentEntry != null) { - currentFileSize += len; - } - } - - /** - * Writes the next tar entry header on the stream - * - * @param entry - * @throws IOException - */ - public void putNextEntry(TarEntry entry) throws IOException { - closeCurrentEntry(); - - byte[] header = new byte[TarConstants.HEADER_BLOCK]; - entry.writeEntryHeader( header ); - - write( header ); - - currentEntry = entry; - } - - /** - * Closes the current tar entry - * - * @throws IOException - */ - protected void closeCurrentEntry() throws IOException { - if (currentEntry != null) { - if (currentEntry.getSize() > currentFileSize) { - throw new IOException( "The current entry[" + currentEntry.getName() + "] of size[" - + currentEntry.getSize() + "] has not been fully written." ); - } - - currentEntry = null; - currentFileSize = 0; - - pad(); - } - } - - /** - * Pads the last content block - * - * @throws IOException - */ - protected void pad() throws IOException { - if (bytesWritten > 0) { - int extra = (int) ( bytesWritten % TarConstants.DATA_BLOCK ); - - if (extra > 0) { - write( new byte[TarConstants.DATA_BLOCK - extra] ); - } - } - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java deleted file mode 100755 index 50165765c0..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * 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. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; - -/** - * @author Kamran - * - */ -public class TarUtils { - /** - * Determines the tar file size of the given folder/file path - * - * @param path - * @return - */ - public static long calculateTarSize(File path) { - return tarSize(path) + TarConstants.EOF_BLOCK; - } - - private static long tarSize(File dir) { - long size = 0; - - if (dir.isFile()) { - return entrySize(dir.length()); - } else { - File[] subFiles = dir.listFiles(); - - if (subFiles != null && subFiles.length > 0) { - for (File file : subFiles) { - if (file.isFile()) { - size += entrySize(file.length()); - } else { - size += tarSize(file); - } - } - } else { - // Empty folder header - return TarConstants.HEADER_BLOCK; - } - } - - return size; - } - - private static long entrySize(long fileSize) { - long size = 0; - size += TarConstants.HEADER_BLOCK; // Header - size += fileSize; // File size - - long extra = size % TarConstants.DATA_BLOCK; - - if (extra > 0) { - size += (TarConstants.DATA_BLOCK - extra); // pad - } - - return size; - } - - public static String trim(String s, char c) { - StringBuffer tmp = new StringBuffer(s); - for (int i = 0; i < tmp.length(); i++) { - if (tmp.charAt(i) != c) { - break; - } else { - tmp.deleteCharAt(i); - } - } - - for (int i = tmp.length() - 1; i >= 0; i--) { - if (tmp.charAt(i) != c) { - break; - } else { - tmp.deleteCharAt(i); - } - } - - return tmp.toString(); - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java deleted file mode 100644 index 7c6a478275..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java +++ /dev/null @@ -1,175 +0,0 @@ - -package org.kivy.android; - -import java.io.InputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.File; - -import android.app.Activity; -import android.util.Log; -import android.widget.Toast; -import android.os.Bundle; - -import org.libsdl.app.SDLActivity; - -import org.renpy.android.ResourceManager; -import org.renpy.android.AssetExtract; - -public class PythonActivity extends SDLActivity { - private static final String TAG = "PythonActivity"; - - public static PythonActivity mActivity = null; - - private ResourceManager resourceManager; - - @Override - protected void onCreate(Bundle savedInstanceState) { - Log.v(TAG, "My oncreate running"); - resourceManager = new ResourceManager(this); - - Log.v(TAG, "Ready to unpack"); - unpackData("private", getFilesDir()); - - Log.v(TAG, "About to do super onCreate"); - super.onCreate(savedInstanceState); - Log.v(TAG, "Did super onCreate"); - - this.mActivity = this; - - String mFilesDirectory = mActivity.getFilesDir().getAbsolutePath(); - Log.v(TAG, "Setting env vars for start.c and Python to use"); - SDLActivity.nativeSetEnv("ANDROID_PRIVATE", mFilesDirectory); - SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", mFilesDirectory); - SDLActivity.nativeSetEnv("ANDROID_APP_PATH", mFilesDirectory); - SDLActivity.nativeSetEnv("PYTHONHOME", mFilesDirectory); - SDLActivity.nativeSetEnv("", mFilesDirectory + ":" + mFilesDirectory + "/lib"); - - - // nativeSetEnv("ANDROID_ARGUMENT", getFilesDir()); - } - - // This is just overrides the normal SDLActivity, which just loads - // SDL2 and main - protected String[] getLibraries() { - return new String[] { - "SDL2", - "SDL2_image", - "SDL2_mixer", - "SDL2_ttf", - "python3.4m", - "python3", - "main" - }; - } - - public void loadLibraries() { - // AND: This should probably be replaced by a call to super - for (String lib : getLibraries()) { - System.loadLibrary(lib); - } - - // System.load(getFilesDir() + "/lib/python3.4/lib-dynload/_io.so"); - System.load(getFilesDir() + "/lib/python3.4/lib-dynload/unicodedata.cpython-34m.so"); - - try { - // System.loadLibrary("ctypes"); - System.load(getFilesDir() + "/lib/python3.4/lib-dynload/_ctypes.cpython-34m.so"); - } catch(UnsatisfiedLinkError e) { - Log.v(TAG, "Unsatisfied linker when loading ctypes"); - } - - Log.v(TAG, "Loaded everything!"); - } - - public void recursiveDelete(File f) { - if (f.isDirectory()) { - for (File r : f.listFiles()) { - recursiveDelete(r); - } - } - f.delete(); - } - - /** - * Show an error using a toast. (Only makes sense from non-UI - * threads.) - */ - public void toastError(final String msg) { - - final Activity thisActivity = this; - - runOnUiThread(new Runnable () { - public void run() { - Toast.makeText(thisActivity, msg, Toast.LENGTH_LONG).show(); - } - }); - - // Wait to show the error. - synchronized (this) { - try { - this.wait(1000); - } catch (InterruptedException e) { - } - } - } - - public void unpackData(final String resource, File target) { - - Log.v(TAG, "UNPACKING!!! " + resource + " " + target.getName()); - - // The version of data in memory and on disk. - String data_version = resourceManager.getString(resource + "_version"); - String disk_version = null; - - Log.v(TAG, "Data version is " + data_version); - - // If no version, no unpacking is necessary. - if (data_version == null) { - return; - } - - // Check the current disk version, if any. - String filesDir = target.getAbsolutePath(); - String disk_version_fn = filesDir + "/" + resource + ".version"; - - try { - byte buf[] = new byte[64]; - InputStream is = new FileInputStream(disk_version_fn); - int len = is.read(buf); - disk_version = new String(buf, 0, len); - is.close(); - } catch (Exception e) { - disk_version = ""; - } - - // If the disk data is out of date, extract it and write the - // version file. - // if (! data_version.equals(disk_version)) { - if (! data_version.equals(disk_version)) { - Log.v(TAG, "Extracting " + resource + " assets."); - - recursiveDelete(target); - target.mkdirs(); - - AssetExtract ae = new AssetExtract(this); - if (!ae.extractTar(resource + ".mp3", target.getAbsolutePath())) { - toastError("Could not extract " + resource + " data."); - } - - try { - // Write .nomedia. - new File(target, ".nomedia").createNewFile(); - - // Write version file. - FileOutputStream os = new FileOutputStream(disk_version_fn); - os.write(data_version.getBytes()); - os.close(); - } catch (Exception e) { - Log.w("python", e); - } - } - - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java deleted file mode 100644 index 76134e8274..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java +++ /dev/null @@ -1,1565 +0,0 @@ -package org.libsdl.app; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.lang.reflect.Method; - -import android.app.*; -import android.content.*; -import android.view.*; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.widget.AbsoluteLayout; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.os.*; -import android.util.Log; -import android.util.SparseArray; -import android.graphics.*; -import android.graphics.drawable.Drawable; -import android.media.*; -import android.hardware.*; - -/** - SDL Activity -*/ -public class SDLActivity extends Activity { - private static final String TAG = "SDL"; - - // Keep track of the paused state - public static boolean mIsPaused, mIsSurfaceReady, mHasFocus; - public static boolean mExitCalledFromJava; - - /** If shared libraries (e.g. SDL or the native application) could not be loaded. */ - public static boolean mBrokenLibraries; - - // If we want to separate mouse and touch events. - // This is only toggled in native code when a hint is set! - public static boolean mSeparateMouseAndTouch; - - // Main components - protected static SDLActivity mSingleton; - protected static SDLSurface mSurface; - protected static View mTextEdit; - protected static ViewGroup mLayout; - protected static SDLJoystickHandler mJoystickHandler; - - // This is what SDL runs in. It invokes SDL_main(), eventually - protected static Thread mSDLThread; - - // Audio - protected static AudioTrack mAudioTrack; - - /** - * This method is called by SDL before loading the native shared libraries. - * It can be overridden to provide names of shared libraries to be loaded. - * The default implementation returns the defaults. It never returns null. - * An array returned by a new implementation must at least contain "SDL2". - * Also keep in mind that the order the libraries are loaded may matter. - * @return names of shared libraries to be loaded (e.g. "SDL2", "main"). - */ - protected String[] getLibraries() { - return new String[] { - "SDL2", - // "SDL2_image", - // "SDL2_mixer", - // "SDL2_net", - // "SDL2_ttf", - "main" - }; - } - - // Load the .so - public void loadLibraries() { - for (String lib : getLibraries()) { - System.loadLibrary(lib); - } - } - - /** - * This method is called by SDL before starting the native application thread. - * It can be overridden to provide the arguments after the application name. - * The default implementation returns an empty array. It never returns null. - * @return arguments for the native application. - */ - protected String[] getArguments() { - return new String[0]; - } - - public static void initialize() { - // The static nature of the singleton and Android quirkyness force us to initialize everything here - // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values - mSingleton = null; - mSurface = null; - mTextEdit = null; - mLayout = null; - mJoystickHandler = null; - mSDLThread = null; - mAudioTrack = null; - mExitCalledFromJava = false; - mBrokenLibraries = false; - mIsPaused = false; - mIsSurfaceReady = false; - mHasFocus = true; - } - - // Setup - @Override - protected void onCreate(Bundle savedInstanceState) { - Log.v("SDL", "Device: " + android.os.Build.DEVICE); - Log.v("SDL", "Model: " + android.os.Build.MODEL); - Log.v("SDL", "onCreate():" + mSingleton); - super.onCreate(savedInstanceState); - - SDLActivity.initialize(); - // So we can call stuff from static callbacks - mSingleton = this; - - // Load shared libraries - String errorMsgBrokenLib = ""; - try { - loadLibraries(); - } catch(UnsatisfiedLinkError e) { - System.err.println(e.getMessage()); - mBrokenLibraries = true; - errorMsgBrokenLib = e.getMessage(); - } catch(Exception e) { - System.err.println(e.getMessage()); - mBrokenLibraries = true; - errorMsgBrokenLib = e.getMessage(); - } - - if (mBrokenLibraries) - { - AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); - dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall." - + System.getProperty("line.separator") - + System.getProperty("line.separator") - + "Error: " + errorMsgBrokenLib); - dlgAlert.setTitle("SDL Error"); - dlgAlert.setPositiveButton("Exit", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog,int id) { - // if this button is clicked, close current activity - SDLActivity.mSingleton.finish(); - } - }); - dlgAlert.setCancelable(false); - dlgAlert.create().show(); - - return; - } - - // Set up the surface - mSurface = new SDLSurface(getApplication()); - - if(Build.VERSION.SDK_INT >= 12) { - mJoystickHandler = new SDLJoystickHandler_API12(); - } - else { - mJoystickHandler = new SDLJoystickHandler(); - } - - mLayout = new AbsoluteLayout(this); - mLayout.addView(mSurface); - - setContentView(mLayout); - } - - // Events - @Override - protected void onPause() { - Log.v("SDL", "onPause()"); - super.onPause(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.handlePause(); - } - - @Override - protected void onResume() { - Log.v("SDL", "onResume()"); - super.onResume(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.handleResume(); - } - - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - Log.v("SDL", "onWindowFocusChanged(): " + hasFocus); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.mHasFocus = hasFocus; - if (hasFocus) { - SDLActivity.handleResume(); - } - } - - @Override - public void onLowMemory() { - Log.v("SDL", "onLowMemory()"); - super.onLowMemory(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.nativeLowMemory(); - } - - @Override - protected void onDestroy() { - Log.v("SDL", "onDestroy()"); - - if (SDLActivity.mBrokenLibraries) { - super.onDestroy(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); - return; - } - - // Send a quit message to the application - SDLActivity.mExitCalledFromJava = true; - SDLActivity.nativeQuit(); - - // Now wait for the SDL thread to quit - if (SDLActivity.mSDLThread != null) { - try { - SDLActivity.mSDLThread.join(); - } catch(Exception e) { - Log.v("SDL", "Problem stopping thread: " + e); - } - SDLActivity.mSDLThread = null; - - //Log.v("SDL", "Finished waiting for SDL thread"); - } - - super.onDestroy(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - - if (SDLActivity.mBrokenLibraries) { - return false; - } - - int keyCode = event.getKeyCode(); - // Ignore certain special keys so they're handled by Android - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || - keyCode == KeyEvent.KEYCODE_VOLUME_UP || - keyCode == KeyEvent.KEYCODE_CAMERA || - keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */ - keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */ - ) { - return false; - } - return super.dispatchKeyEvent(event); - } - - /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed - * is the first to be called, mIsSurfaceReady should still be set - * to 'true' during the call to onPause (in a usual scenario). - */ - public static void handlePause() { - if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) { - SDLActivity.mIsPaused = true; - SDLActivity.nativePause(); - mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false); - } - } - - /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready. - * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume - * every time we get one of those events, only if it comes after surfaceDestroyed - */ - public static void handleResume() { - if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) { - SDLActivity.mIsPaused = false; - SDLActivity.nativeResume(); - mSurface.handleResume(); - } - } - - /* The native thread has finished */ - public static void handleNativeExit() { - SDLActivity.mSDLThread = null; - mSingleton.finish(); - } - - - // Messages from the SDLMain thread - static final int COMMAND_CHANGE_TITLE = 1; - static final int COMMAND_UNUSED = 2; - static final int COMMAND_TEXTEDIT_HIDE = 3; - static final int COMMAND_SET_KEEP_SCREEN_ON = 5; - - protected static final int COMMAND_USER = 0x8000; - - /** - * This method is called by SDL if SDL did not handle a message itself. - * This happens if a received message contains an unsupported command. - * Method can be overwritten to handle Messages in a different class. - * @param command the command of the message. - * @param param the parameter of the message. May be null. - * @return if the message was handled in overridden method. - */ - protected boolean onUnhandledMessage(int command, Object param) { - return false; - } - - /** - * A Handler class for Messages from native SDL applications. - * It uses current Activities as target (e.g. for the title). - * static to prevent implicit references to enclosing object. - */ - protected static class SDLCommandHandler extends Handler { - @Override - public void handleMessage(Message msg) { - Context context = getContext(); - if (context == null) { - Log.e(TAG, "error handling message, getContext() returned null"); - return; - } - switch (msg.arg1) { - case COMMAND_CHANGE_TITLE: - if (context instanceof Activity) { - ((Activity) context).setTitle((String)msg.obj); - } else { - Log.e(TAG, "error handling message, getContext() returned no Activity"); - } - break; - case COMMAND_TEXTEDIT_HIDE: - if (mTextEdit != null) { - mTextEdit.setVisibility(View.GONE); - - InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); - } - break; - case COMMAND_SET_KEEP_SCREEN_ON: - { - Window window = ((Activity) context).getWindow(); - if (window != null) { - if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } else { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - } - break; - } - default: - if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { - Log.e(TAG, "error handling message, command is " + msg.arg1); - } - } - } - } - - // Handler for the messages - Handler commandHandler = new SDLCommandHandler(); - - // Send a message from the SDLMain thread - boolean sendCommand(int command, Object data) { - Message msg = commandHandler.obtainMessage(); - msg.arg1 = command; - msg.obj = data; - return commandHandler.sendMessage(msg); - } - - // C functions we call - public static native int nativeInit(Object arguments); - public static native void nativeLowMemory(); - public static native void nativeQuit(); - public static native void nativePause(); - public static native void nativeResume(); - public static native void onNativeResize(int x, int y, int format, float rate); - public static native int onNativePadDown(int device_id, int keycode); - public static native int onNativePadUp(int device_id, int keycode); - public static native void onNativeJoy(int device_id, int axis, - float value); - public static native void onNativeHat(int device_id, int hat_id, - int x, int y); - public static native void nativeSetEnv(String j_name, String j_value); - public static native void onNativeKeyDown(int keycode); - public static native void onNativeKeyUp(int keycode); - public static native void onNativeKeyboardFocusLost(); - public static native void onNativeMouse(int button, int action, float x, float y); - public static native void onNativeTouch(int touchDevId, int pointerFingerId, - int action, float x, - float y, float p); - public static native void onNativeAccel(float x, float y, float z); - public static native void onNativeSurfaceChanged(); - public static native void onNativeSurfaceDestroyed(); - public static native void nativeFlipBuffers(); - public static native int nativeAddJoystick(int device_id, String name, - int is_accelerometer, int nbuttons, - int naxes, int nhats, int nballs); - public static native int nativeRemoveJoystick(int device_id); - public static native String nativeGetHint(String name); - - /** - * This method is called by SDL using JNI. - */ - public static void flipBuffers() { - SDLActivity.nativeFlipBuffers(); - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean setActivityTitle(String title) { - // Called from SDLMain() thread and can't directly affect the view - return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean sendMessage(int command, int param) { - return mSingleton.sendCommand(command, Integer.valueOf(param)); - } - - /** - * This method is called by SDL using JNI. - */ - public static Context getContext() { - return mSingleton; - } - - /** - * This method is called by SDL using JNI. - * @return result of getSystemService(name) but executed on UI thread. - */ - public Object getSystemServiceFromUiThread(final String name) { - final Object lock = new Object(); - final Object[] results = new Object[2]; // array for writable variables - synchronized (lock) { - runOnUiThread(new Runnable() { - @Override - public void run() { - synchronized (lock) { - results[0] = getSystemService(name); - results[1] = Boolean.TRUE; - lock.notify(); - } - } - }); - if (results[1] == null) { - try { - lock.wait(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - } - return results[0]; - } - - static class ShowTextInputTask implements Runnable { - /* - * This is used to regulate the pan&scan method to have some offset from - * the bottom edge of the input region and the top edge of an input - * method (soft keyboard) - */ - static final int HEIGHT_PADDING = 15; - - public int x, y, w, h; - - public ShowTextInputTask(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - @Override - public void run() { - AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams( - w, h + HEIGHT_PADDING, x, y); - - if (mTextEdit == null) { - mTextEdit = new DummyEdit(getContext()); - - mLayout.addView(mTextEdit, params); - } else { - mTextEdit.setLayoutParams(params); - } - - mTextEdit.setVisibility(View.VISIBLE); - mTextEdit.requestFocus(); - - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mTextEdit, 0); - } - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean showTextInput(int x, int y, int w, int h) { - // Transfer the task to the main thread as a Runnable - return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h)); - } - - /** - * This method is called by SDL using JNI. - */ - public static Surface getNativeSurface() { - return SDLActivity.mSurface.getNativeSurface(); - } - - // Audio - - /** - * This method is called by SDL using JNI. - */ - public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - - Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); - - if (mAudioTrack == null) { - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); - - // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid - // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java - // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState() - - if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) { - Log.e("SDL", "Failed during initialization of Audio Track"); - mAudioTrack = null; - return -1; - } - - mAudioTrack.play(); - } - - Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - return 0; - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteShortBuffer(short[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteByteBuffer(byte[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(byte)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioQuit() { - if (mAudioTrack != null) { - mAudioTrack.stop(); - mAudioTrack = null; - } - } - - // Input - - /** - * This method is called by SDL using JNI. - * @return an array which may be empty but is never null. - */ - public static int[] inputGetInputDeviceIds(int sources) { - int[] ids = InputDevice.getDeviceIds(); - int[] filtered = new int[ids.length]; - int used = 0; - for (int i = 0; i < ids.length; ++i) { - InputDevice device = InputDevice.getDevice(ids[i]); - if ((device != null) && ((device.getSources() & sources) != 0)) { - filtered[used++] = device.getId(); - } - } - return Arrays.copyOf(filtered, used); - } - - // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance - public static boolean handleJoystickMotionEvent(MotionEvent event) { - return mJoystickHandler.handleMotionEvent(event); - } - - /** - * This method is called by SDL using JNI. - */ - public static void pollInputDevices() { - if (SDLActivity.mSDLThread != null) { - mJoystickHandler.pollInputDevices(); - } - } - - // APK extension files support - - /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */ - private Object expansionFile; - - /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */ - private Method expansionFileMethod; - - /** - * This method is called by SDL using JNI. - */ - public InputStream openAPKExtensionInputStream(String fileName) throws IOException { - // Get a ZipResourceFile representing a merger of both the main and patch files - if (expansionFile == null) { - Integer mainVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION")); - Integer patchVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION")); - - try { - // To avoid direct dependency on Google APK extension library that is - // not a part of Android SDK we access it using reflection - expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport") - .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class) - .invoke(null, this, mainVersion, patchVersion); - - expansionFileMethod = expansionFile.getClass() - .getMethod("getInputStream", String.class); - } catch (Exception ex) { - ex.printStackTrace(); - expansionFile = null; - expansionFileMethod = null; - } - } - - // Get an input stream for a known file inside the expansion file ZIPs - InputStream fileStream; - try { - fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName); - } catch (Exception ex) { - ex.printStackTrace(); - fileStream = null; - } - - if (fileStream == null) { - throw new IOException(); - } - - return fileStream; - } - - // Messagebox - - /** Result of current messagebox. Also used for blocking the calling thread. */ - protected final int[] messageboxSelection = new int[1]; - - /** Id of current dialog. */ - protected int dialogs = 0; - - /** - * This method is called by SDL using JNI. - * Shows the messagebox from UI thread and block calling thread. - * buttonFlags, buttonIds and buttonTexts must have same length. - * @param buttonFlags array containing flags for every button. - * @param buttonIds array containing id for every button. - * @param buttonTexts array containing text for every button. - * @param colors null for default or array of length 5 containing colors. - * @return button id or -1. - */ - public int messageboxShowMessageBox( - final int flags, - final String title, - final String message, - final int[] buttonFlags, - final int[] buttonIds, - final String[] buttonTexts, - final int[] colors) { - - messageboxSelection[0] = -1; - - // sanity checks - - if ((buttonFlags.length != buttonIds.length) && (buttonIds.length != buttonTexts.length)) { - return -1; // implementation broken - } - - // collect arguments for Dialog - - final Bundle args = new Bundle(); - args.putInt("flags", flags); - args.putString("title", title); - args.putString("message", message); - args.putIntArray("buttonFlags", buttonFlags); - args.putIntArray("buttonIds", buttonIds); - args.putStringArray("buttonTexts", buttonTexts); - args.putIntArray("colors", colors); - - // trigger Dialog creation on UI thread - - runOnUiThread(new Runnable() { - @Override - public void run() { - showDialog(dialogs++, args); - } - }); - - // block the calling thread - - synchronized (messageboxSelection) { - try { - messageboxSelection.wait(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - return -1; - } - } - - // return selected value - - return messageboxSelection[0]; - } - - @Override - protected Dialog onCreateDialog(int ignore, Bundle args) { - - // TODO set values from "flags" to messagebox dialog - - // get colors - - int[] colors = args.getIntArray("colors"); - int backgroundColor; - int textColor; - int buttonBorderColor; - int buttonBackgroundColor; - int buttonSelectedColor; - if (colors != null) { - int i = -1; - backgroundColor = colors[++i]; - textColor = colors[++i]; - buttonBorderColor = colors[++i]; - buttonBackgroundColor = colors[++i]; - buttonSelectedColor = colors[++i]; - } else { - backgroundColor = Color.TRANSPARENT; - textColor = Color.TRANSPARENT; - buttonBorderColor = Color.TRANSPARENT; - buttonBackgroundColor = Color.TRANSPARENT; - buttonSelectedColor = Color.TRANSPARENT; - } - - // create dialog with title and a listener to wake up calling thread - - final Dialog dialog = new Dialog(this); - dialog.setTitle(args.getString("title")); - dialog.setCancelable(false); - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface unused) { - synchronized (messageboxSelection) { - messageboxSelection.notify(); - } - } - }); - - // create text - - TextView message = new TextView(this); - message.setGravity(Gravity.CENTER); - message.setText(args.getString("message")); - if (textColor != Color.TRANSPARENT) { - message.setTextColor(textColor); - } - - // create buttons - - int[] buttonFlags = args.getIntArray("buttonFlags"); - int[] buttonIds = args.getIntArray("buttonIds"); - String[] buttonTexts = args.getStringArray("buttonTexts"); - - final SparseArray