[Scummvm-cvs-logs] SF.net SVN: scummvm:[49499] scummvm/branches/gsoc2010-opengl

vgvgf at users.sourceforge.net vgvgf at users.sourceforge.net
Tue Jun 8 05:31:28 CEST 2010


Revision: 49499
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49499&view=rev
Author:   vgvgf
Date:     2010-06-08 03:31:27 +0000 (Tue, 08 Jun 2010)

Log Message:
-----------
Merged from trunk.

Modified Paths:
--------------
    scummvm/branches/gsoc2010-opengl/AUTHORS
    scummvm/branches/gsoc2010-opengl/COPYRIGHT
    scummvm/branches/gsoc2010-opengl/NEWS
    scummvm/branches/gsoc2010-opengl/README
    scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.cpp
    scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.h
    scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/ds/arm7/source/main.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/ds/arm9/dist/readme_ds.txt
    scummvm/branches/gsoc2010-opengl/backends/platform/ds/arm9/makefile
    scummvm/branches/gsoc2010-opengl/backends/platform/ds/arm9/source/dsmain.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2x/gp2x-common.h
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2x/gp2x.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2x/graphics.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/build/build.sh
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/build/bundle.sh
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/build/clean.sh
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/build/config.sh
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/gp2xwiz-events.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/gp2xwiz/gp2xwiz-graphics.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/iphone/iphone_common.h
    scummvm/branches/gsoc2010-opengl/backends/platform/iphone/iphone_video.h
    scummvm/branches/gsoc2010-opengl/backends/platform/iphone/iphone_video.m
    scummvm/branches/gsoc2010-opengl/backends/platform/iphone/osys_main.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/iphone/osys_video.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/linuxmoto/linuxmoto-graphics.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/ps2/systemps2.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/ps2/systemps2.h
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/Makefile
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/display_client.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/module.mk
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/osys_psp.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/osys_psp.h
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/psp.spec
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/thread.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/thread.h
    scummvm/branches/gsoc2010-opengl/backends/platform/samsungtv/samsungtv.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/symbian/src/SymbianOS.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/wince/wince-sdl.cpp
    scummvm/branches/gsoc2010-opengl/base/commandLine.cpp
    scummvm/branches/gsoc2010-opengl/common/str.h
    scummvm/branches/gsoc2010-opengl/common/stream.h
    scummvm/branches/gsoc2010-opengl/common/system.h
    scummvm/branches/gsoc2010-opengl/common/textconsole.cpp
    scummvm/branches/gsoc2010-opengl/common/unzip.cpp
    scummvm/branches/gsoc2010-opengl/configure
    scummvm/branches/gsoc2010-opengl/dists/iphone/scummvm.xcodeproj/project.pbxproj
    scummvm/branches/gsoc2010-opengl/engines/dialogs.cpp
    scummvm/branches/gsoc2010-opengl/engines/dialogs.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/cell.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/cursor.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/debug.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/debug.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/detection.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/font.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/font.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/graphics.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/graphics.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/groovie.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/groovie.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/music.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/music.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/player.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/resource.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/roq.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/script.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/script.h
    scummvm/branches/gsoc2010-opengl/engines/groovie/vdx.cpp
    scummvm/branches/gsoc2010-opengl/engines/groovie/vdx.h
    scummvm/branches/gsoc2010-opengl/engines/m4/animation.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/animation.h
    scummvm/branches/gsoc2010-opengl/engines/m4/assets.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/assets.h
    scummvm/branches/gsoc2010-opengl/engines/m4/compression.h
    scummvm/branches/gsoc2010-opengl/engines/m4/console.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/console.h
    scummvm/branches/gsoc2010-opengl/engines/m4/converse.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/dialogs.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/font.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/font.h
    scummvm/branches/gsoc2010-opengl/engines/m4/graphics.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/graphics.h
    scummvm/branches/gsoc2010-opengl/engines/m4/gui.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/m4.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/m4.h
    scummvm/branches/gsoc2010-opengl/engines/m4/m4_views.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_anim.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_anim.h
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_logic.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_logic.h
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_menus.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_scene.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_scene.h
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_views.cpp
    scummvm/branches/gsoc2010-opengl/engines/m4/mads_views.h
    scummvm/branches/gsoc2010-opengl/engines/m4/viewmgr.h
    scummvm/branches/gsoc2010-opengl/engines/mohawk/detection.cpp
    scummvm/branches/gsoc2010-opengl/engines/mohawk/riven.cpp
    scummvm/branches/gsoc2010-opengl/engines/mohawk/riven.h
    scummvm/branches/gsoc2010-opengl/engines/mohawk/riven_external.cpp
    scummvm/branches/gsoc2010-opengl/engines/mohawk/riven_external.h
    scummvm/branches/gsoc2010-opengl/engines/mohawk/riven_scripts.cpp
    scummvm/branches/gsoc2010-opengl/engines/mohawk/video.cpp
    scummvm/branches/gsoc2010-opengl/engines/mohawk/video.h
    scummvm/branches/gsoc2010-opengl/engines/parallaction/parser_ns.cpp
    scummvm/branches/gsoc2010-opengl/engines/saga/saga.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/console.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/console.h
    scummvm/branches/gsoc2010-opengl/engines/sci/detection.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/features.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/game.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kernel.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kernel.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kernel32.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kevent.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kfile.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kgraphics.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/klists.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kmisc.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kmovement.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kparse.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kpathing.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kscripts.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/kstring.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/savegame.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/savegame.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/script.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/scriptdebug.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/seg_manager.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/seg_manager.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/segment.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/segment.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/selector.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/selector.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/state.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/state.h
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/vm.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/engine/vm.h
    scummvm/branches/gsoc2010-opengl/engines/sci/event.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/animate.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/compare.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/controls.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/coordadjuster.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/frameout.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/maciconbar.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/menu.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/paint16.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/palette.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/picture.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/graphics/picture.h
    scummvm/branches/gsoc2010-opengl/engines/sci/module.mk
    scummvm/branches/gsoc2010-opengl/engines/sci/parser/said.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/parser/said.y
    scummvm/branches/gsoc2010-opengl/engines/sci/resource.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/resource.h
    scummvm/branches/gsoc2010-opengl/engines/sci/sci.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/audio.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/midiparser_sci.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/midiparser_sci.h
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/music.cpp
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/music.h
    scummvm/branches/gsoc2010-opengl/engines/sci/sound/soundcmd.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/debugger.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/dialogs.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/dialogs.h
    scummvm/branches/gsoc2010-opengl/engines/scumm/he/resource_he.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/imuse/instrument.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/input.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/scumm.cpp
    scummvm/branches/gsoc2010-opengl/engines/scumm/scumm.h
    scummvm/branches/gsoc2010-opengl/engines/tinsel/handle.cpp
    scummvm/branches/gsoc2010-opengl/engines/tinsel/saveload.cpp
    scummvm/branches/gsoc2010-opengl/engines/tucker/sequences.cpp
    scummvm/branches/gsoc2010-opengl/engines/tucker/tucker.h
    scummvm/branches/gsoc2010-opengl/graphics/font.h
    scummvm/branches/gsoc2010-opengl/graphics/video/avi_decoder.cpp
    scummvm/branches/gsoc2010-opengl/graphics/video/qt_decoder.cpp
    scummvm/branches/gsoc2010-opengl/graphics/video/qt_decoder.h
    scummvm/branches/gsoc2010-opengl/graphics/video/smk_decoder.cpp
    scummvm/branches/gsoc2010-opengl/graphics/video/smk_decoder.h
    scummvm/branches/gsoc2010-opengl/gui/about.cpp
    scummvm/branches/gsoc2010-opengl/gui/credits.h
    scummvm/branches/gsoc2010-opengl/gui/editable.cpp
    scummvm/branches/gsoc2010-opengl/gui/themes/default.inc
    scummvm/branches/gsoc2010-opengl/gui/themes/scummclassic/classic_layout.stx
    scummvm/branches/gsoc2010-opengl/gui/themes/scummclassic/classic_layout_lowres.stx
    scummvm/branches/gsoc2010-opengl/gui/themes/scummclassic.zip
    scummvm/branches/gsoc2010-opengl/gui/themes/scummmodern/scummmodern_layout.stx
    scummvm/branches/gsoc2010-opengl/gui/themes/scummmodern/scummmodern_layout_lowres.stx
    scummvm/branches/gsoc2010-opengl/gui/themes/scummmodern.zip
    scummvm/branches/gsoc2010-opengl/ports.mk
    scummvm/branches/gsoc2010-opengl/sound/decoders/adpcm.cpp
    scummvm/branches/gsoc2010-opengl/sound/decoders/mp3.cpp
    scummvm/branches/gsoc2010-opengl/sound/decoders/voc.cpp
    scummvm/branches/gsoc2010-opengl/sound/decoders/vorbis.cpp
    scummvm/branches/gsoc2010-opengl/sound/midiparser.cpp
    scummvm/branches/gsoc2010-opengl/sound/mods/rjp1.cpp
    scummvm/branches/gsoc2010-opengl/test/common/str.h
    scummvm/branches/gsoc2010-opengl/tools/create_msvc/create_msvc.cpp
    scummvm/branches/gsoc2010-opengl/tools/credits.pl
    scummvm/branches/gsoc2010-opengl/tools/update-version.pl

Added Paths:
-----------
    scummvm/branches/gsoc2010-opengl/backends/platform/android/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build
    scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/android/android.mk
    scummvm/branches/gsoc2010-opengl/backends/platform/android/asset-archive.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/android/asset-archive.h
    scummvm/branches/gsoc2010-opengl/backends/platform/android/module.mk
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/Event.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/Unpacker.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/scummvm-android-themeengine.patch
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/mp3.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/psp/mp3.h
    scummvm/branches/gsoc2010-opengl/dists/android/
    scummvm/branches/gsoc2010-opengl/dists/android/mkmanifest.pl
    scummvm/branches/gsoc2010-opengl/dists/android/res/
    scummvm/branches/gsoc2010-opengl/dists/android/res/drawable/
    scummvm/branches/gsoc2010-opengl/dists/android/res/drawable/gradient.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/main.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/splash.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/values/
    scummvm/branches/gsoc2010-opengl/dists/android/res/values/strings.xml
    scummvm/branches/gsoc2010-opengl/dists/os2/
    scummvm/branches/gsoc2010-opengl/dists/os2/readme.os2
    scummvm/branches/gsoc2010-opengl/dists/os2/scummvm.ico
    scummvm/branches/gsoc2010-opengl/engines/sci/resource_audio.cpp

Removed Paths:
-------------
    scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build
    scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/android/android.mk
    scummvm/branches/gsoc2010-opengl/backends/platform/android/asset-archive.cpp
    scummvm/branches/gsoc2010-opengl/backends/platform/android/asset-archive.h
    scummvm/branches/gsoc2010-opengl/backends/platform/android/module.mk
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/Event.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/org/inodes/gus/scummvm/Unpacker.java
    scummvm/branches/gsoc2010-opengl/backends/platform/android/scummvm-android-themeengine.patch
    scummvm/branches/gsoc2010-opengl/dists/android/mkmanifest.pl
    scummvm/branches/gsoc2010-opengl/dists/android/res/
    scummvm/branches/gsoc2010-opengl/dists/android/res/drawable/
    scummvm/branches/gsoc2010-opengl/dists/android/res/drawable/gradient.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/main.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/layout/splash.xml
    scummvm/branches/gsoc2010-opengl/dists/android/res/values/
    scummvm/branches/gsoc2010-opengl/dists/android/res/values/strings.xml
    scummvm/branches/gsoc2010-opengl/dists/os2/readme.os2
    scummvm/branches/gsoc2010-opengl/dists/os2/scummvm.ico

Property Changed:
----------------
    scummvm/branches/gsoc2010-opengl/
    scummvm/branches/gsoc2010-opengl/backends/timer/
    scummvm/branches/gsoc2010-opengl/backends/timer/psp/
    scummvm/branches/gsoc2010-opengl/engines/draci/script.cpp
    scummvm/branches/gsoc2010-opengl/engines/draci/script.h


Property changes on: scummvm/branches/gsoc2010-opengl
___________________________________________________________________
Modified: svn:mergeinfo
   - /scummvm/branches/gsoc2009-draci:41389-44325
   + /scummvm/branches/gsoc2009-draci:41389-44325
/scummvm/trunk:49204-49497

Modified: scummvm/branches/gsoc2010-opengl/AUTHORS
===================================================================
--- scummvm/branches/gsoc2010-opengl/AUTHORS	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/AUTHORS	2010-06-08 03:31:27 UTC (rev 49499)
@@ -166,6 +166,9 @@
 
   Backend Teams
   -------------
+    Android:
+       Angus Lees
+
     Dreamcast:
        Marcus Comstedt
 

Modified: scummvm/branches/gsoc2010-opengl/COPYRIGHT
===================================================================
--- scummvm/branches/gsoc2010-opengl/COPYRIGHT	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/COPYRIGHT	2010-06-08 03:31:27 UTC (rev 49499)
@@ -48,6 +48,7 @@
 Pawel Kolodziejski
 Mutwin Kraus
 Andrew Kurushin
+Angus Lees
 Claudio Matsuoka
 Thomas Mayer
 Neil Millstone

Modified: scummvm/branches/gsoc2010-opengl/NEWS
===================================================================
--- scummvm/branches/gsoc2010-opengl/NEWS	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/NEWS	2010-06-08 03:31:27 UTC (rev 49499)
@@ -2,13 +2,23 @@
         http://scummvm.svn.sourceforge.net/viewvc/scummvm/?view=log
 
 1.2.0 (????-??-??)
+ New Ports:
+   - Added Android port.
+
+ General:
+   - Switched to the "fast" DOSBox OPL emulator.
+   - Fixed a crash in the rjp1 player code affecting the FOTAQ Amiga version.
+
+ Groovie:
+   - Added support for the Macintosh version of The 7th Guest.
+   - Added support for custom MT-32 instruments.
+
  PSP port:
    - Switched to new backend design which fixes minor graphical issues,
      speeds things up, and provides 16-bit support.
+   - Enabled playback of MP3 files using the hardware decoder (ME). This means that
+     the port is now optimized for MP3 playback (as opposed to OGG).
 
- General:
-   - Switched to the "fast" DOSBox OPL emulator.
-
 1.1.2 (????-??-??)
   Broken Sword 2
    - Fixed missing speech in some cutscenes.
@@ -17,7 +27,7 @@
 
 1.1.1 (2010-05-02)
  New Ports:
-   - Added Nintendo 64 Port. (Actually added in 1.1.0, but forgot to mention it. oops)
+   - Added Nintendo 64 port. (Actually added in 1.1.0, but forgot to mention it. oops)
 
  General:
    - Fixed several minor bugs here and there.

Modified: scummvm/branches/gsoc2010-opengl/README
===================================================================
--- scummvm/branches/gsoc2010-opengl/README	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/README	2010-06-08 03:31:27 UTC (rev 49499)
@@ -81,9 +81,10 @@
 and how well on the compatibility page. ScummVM is continually
 improving, so check back often.
 
-Among the systems on which you can play those games are Windows, Linux,
-Mac OS X, Dreamcast, PocketPC, PalmOS, AmigaOS, BeOS, OS/2, PSP, PS2,
-SymbianOS/EPOC, iPhone and many more.
+Among the systems on which you can play those games are regular desktop
+computers (running Windows, Linux, Mac OS X, ...), game consoles
+(Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), smartphones (Android,
+iPhone, PocketPC, Symbian ...) and more.
 
 At this time ScummVM should be considered beta software, and is still
 under heavy development. Be aware that whilst we attempt to make sure
@@ -843,21 +844,25 @@
 
 Supported platforms include (but are not limited to):
 
-        UNIX            (Linux, Solaris, IRIX, *BSD)
+        UNIX            (Linux, Solaris, IRIX, *BSD, ...)
         Windows
         Windows CE and Windows Mobile  (including Smartphones and PocketPCs)
         Mac OS X
         AmigaOS
+        Android
         BeOS
         Dreamcast
-        iPhone          (also includes the iPod Touch)
+        GP2x
+        iPhone          (also includes iPod Touch and iPad)
+        Maemo           (Nokia Internet tablets 770, N800, N810, N900)
+        Nintendo 64
         Nintendo DS
+        Nintendo Wii
+        OS/2
         PalmOS
         PlayStation 2
         PlayStation Portable
-        RISC OS
         Symbian
-        Maemo (Nokia Internet tablets 770, N800, N810, N900)
 
 The Dreamcast port does not support The Curse of Monkey Island, nor The
 Dig. The PalmOS port does not support The Curse of Monkey Island,
@@ -865,6 +870,8 @@
 only work on some Palm devices (those with a large dynamic heap). The
 Nintendo DS port does not support Full Throttle, The Dig, or The Curse
 of Monkey Island.
+For more platform specific limitations, please refer to our Wiki:
+  http://wiki.scummvm.org/index.php/Platforms
 
 In the Macintosh port, the right mouse button is emulated via Cmd-Click
 (that is, you click the mouse button while holding the

Modified: scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.cpp
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.cpp	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.cpp	2010-06-08 03:31:27 UTC (rev 49499)
@@ -24,6 +24,8 @@
  */
 #ifdef __PSP__
 
+#include <pspiofilemgr_stat.h>
+#include <pspiofilemgr.h>
 #include <SDL/SDL_thread.h>
 #include <SDL/SDL_mutex.h>
 
@@ -32,28 +34,48 @@
 
 #include <errno.h>
 
-//#define __PSP_PRINT_TO_FILE__
-//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
+#define MIN2(a,b) ((a < b) ? a : b)
+#define MIN3(a,b,c) ( (a < b) ? (a < c ? a : c) : (b < c ? b : c) )
+
+//#define __PSP_PRINT_TO_FILE__ /* For debugging suspend stuff, we have no screen output */
+//#define __PSP_DEBUG_FUNCS__ 	/* For debugging function calls */
 //#define __PSP_DEBUG_PRINT__	/* For debug printouts */
+
 #include "backends/platform/psp/trace.h"
 
+//#define DEBUG_BUFFERS					/* to see the contents of the buffers being read */
+
+#ifdef DEBUG_BUFFERS
+void printBuffer(byte *ptr, uint32 len) {
+	uint32 printLen = len <= 10 ? len : 10;
+	
+	for (int i = 0; i < printLen; i++) {
+		PSP_INFO_PRINT("%x ", ptr[i]);		
+	}
+	
+	if (len > 10) {
+		PSP_INFO_PRINT("... ");
+		for (int i = len - 10; i < len; i++)
+			PSP_INFO_PRINT("%x ", ptr[i]);
+	}
+	
+	PSP_INFO_PRINT("\n");
+}
+#endif
+
+
 PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
-		: StdioStream((void *)1), _path(path), _writeMode(writeMode) {
+		: StdioStream((void *)1), _path(path), _writeMode(writeMode),
+		  _ferror(false), _pos(0),
+		  _physicalPos(0), _fileSize(0), _inCache(false), _eos(false),
+		  _cacheStartOffset(-1), _cache(0),
+		  _errorSuspend(0), _errorSource(0),
+		  _errorPos(0), _errorHandle(0), _suspendCount(0) {
 	DEBUG_ENTER_FUNC();
 
-	assert(!path.empty());
+	// assert(!path.empty());	// do we need this?
 
 	_handle = (void *)0;		// Need to do this since base class asserts not 0.
-	_ferror = false;
-	_feof = false;
-	_pos = 0;
-
-	/* for error checking */
-	_errorSuspend = 0;
-	_errorSource = 0;
-	_errorPos = 0;
-	_errorHandle = 0;
-	_suspendCount = 0;
 }
 
 PSPIoStream::~PSPIoStream() {
@@ -63,9 +85,12 @@
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 
 	PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
-	// Must do this before fclose() or resume() will reopen.
+									  // Must do this before fclose() or resume() will reopen.
 
-	fclose((FILE *)_handle);	// We don't need a critical section(?). Worst case, the handle gets closed on its own
+	fclose((FILE *)_handle);		  // We don't need a critical section. Worst case, the handle gets closed on its own
+	
+	if (_cache)
+		free(_cache);
 
 	PowerMan.endCriticalSection();
 }
@@ -82,6 +107,17 @@
 
 	_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); 	// open
 
+	if (_handle) {
+		// Get the file size. This way is much faster than going to the end of the file and back
+		SceIoStat stat;
+		sceIoGetstat(_path.c_str(), &stat);
+		_fileSize = *((uint32 *)(void *)&stat.st_size);	// 4GB file is big enough for us
+		PSP_DEBUG_PRINT("%s filesize = %d\n", _path.c_str(), _fileSize);
+	
+		// Allocate the cache
+		_cache = (char *)memalign(64, CACHE_SIZE);
+	}
+
 	PowerMan.registerSuspend(this);	 // Register with the powermanager to be suspended
 
 	PowerMan.endCriticalSection();
@@ -91,120 +127,215 @@
 
 bool PSPIoStream::err() const {
 	DEBUG_ENTER_FUNC();
-	if (_ferror)
-		PSP_ERROR("mem_ferror[%d], source[%d], suspend error[%d], pos[%d], _errorPos[%d], _errorHandle[%p], suspendCount[%d]\n",
-		          _ferror, _errorSource, _errorSuspend, _pos, _errorPos, _errorHandle, _suspendCount);
+	
+	if (_ferror)	// We dump since no printing to screen with suspend
+		PSP_ERROR("mem_ferror[%d], source[%d], suspend error[%d], pos[%d], \
+		_errorPos[%d], _errorHandle[%p], suspendCount[%d]\n",
+		          _ferror, _errorSource, _errorSuspend, _pos,
+				  _errorPos, _errorHandle, _suspendCount);
 
 	return _ferror;
 }
 
 void PSPIoStream::clearErr() {
-	_ferror = false;	// Remove regular error bit
+	_ferror = false;
 }
 
 bool PSPIoStream::eos() const {
-	return _feof;
+	return _eos;
 }
 
 int32 PSPIoStream::pos() const {
 	return _pos;
 }
 
-
 int32 PSPIoStream::size() const {
-	DEBUG_ENTER_FUNC();
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
-		PSP_DEBUG_PRINT_FUNC("Suspended\n");
-
-	fseek((FILE *)_handle, 0, SEEK_END);
-	int32 length = ftell((FILE *)_handle);
-	fseek((FILE *)_handle, _pos, SEEK_SET);
-
-	if (_pos < 0 || length < 0) {	// Check for errors
-		_errorSource = 2;
-		PSP_ERROR("pos[%d] or length[%d] < 0!\n", _pos, length);
-		_ferror = true;
-		length = -1;				// If our oldPos is bad, we want length to be bad too to signal
-		clearerr((FILE *)_handle);
-	}
-
-	PowerMan.endCriticalSection();
-
-	return length;
+	return _fileSize;
 }
 
 bool PSPIoStream::seek(int32 offs, int whence) {
 	DEBUG_ENTER_FUNC();
-
-	// Check if we can access the file
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
-		PSP_DEBUG_PRINT_FUNC("Suspended\n");
-
-	int ret = fseek((FILE *)_handle, offs, whence);
-
-	if (ret != 0) {
+	PSP_DEBUG_PRINT_FUNC("offset[0x%x], whence[%d], _pos[0x%x], _physPos[0x%x]\n", offs, whence, _pos, _physicalPos);
+	_eos = false;
+	
+	int32 posToSearchFor = 0;
+	switch (whence) {
+	case SEEK_CUR:
+		posToSearchFor = _pos;
+		break;
+	case SEEK_END:
+		posToSearchFor = _fileSize;	// unsure. Does it take us here or to EOS - 1?
+		break;
+	}
+	posToSearchFor += offs;
+	
+	// Check for bad values
+	if (posToSearchFor < 0) {
 		_ferror = true;
-		PSP_ERROR("fseek returned with [%d], non-zero\n", ret);
-		clearerr((FILE *)_handle);
-		_feof = feof((FILE *)_handle);
-		_errorSource = 3;
-	} else {					// everything ok
-		_feof = false;		// Reset eof flag since we know it was ok
+		return false;
 	}
-
-	_pos = ftell((FILE *)_handle);	// update pos
-
-	PowerMan.endCriticalSection();
-
-	return (ret == 0);
+	
+	if (posToSearchFor > _fileSize) {
+		_ferror = true;
+		_eos = true;
+		return false;
+	}
+	
+	// See if we can find it in cache
+	if (isOffsetInCache(posToSearchFor)) {
+		PSP_DEBUG_PRINT("seek offset[0x%x] found in cache. Cache starts[0x%x]\n", posToSearchFor, _cacheStartOffset);
+		_inCache = true;		
+	} else {	// not in cache
+		_inCache = false;		
+	}	
+	_pos = posToSearchFor;		
+	return true;
 }
 
 uint32 PSPIoStream::read(void *ptr, uint32 len) {
 	DEBUG_ENTER_FUNC();
-	// Check if we can access the file
+	PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x], ptr[%p]\n", _path.c_str(), len, ptr);
+
+	if (_ferror || _eos)
+		return 0;
+		
+	byte *destPtr = (byte *)ptr;
+	uint32 lenFromFile = len;		// how much we read from the actual file
+	uint32 lenFromCache = 0;		// how much we read from cache
+	uint32 lenRemainingInFile = _fileSize - _pos;
+	
+	if (lenFromFile > lenRemainingInFile) {
+		lenFromFile = lenRemainingInFile;
+		_eos = true;
+	}	
+	
+	// Are we in cache?
+	if (_inCache && isCacheValid()) {
+		uint32 offsetInCache = _pos - _cacheStartOffset;
+		// We can read at most what's in the cache or the remaining size of the file
+		lenFromCache = MIN2(lenFromFile, CACHE_SIZE - offsetInCache); // unsure
+		
+		PSP_DEBUG_PRINT("reading 0x%x bytes from cache to %p. pos[0x%x] physPos[0x%x] cacheStart[0x%x]\n", lenFromCache, destPtr, _pos, _physicalPos, _cacheStartOffset);
+		
+		memcpy(destPtr, &_cache[offsetInCache], lenFromCache);
+		_pos += lenFromCache;		
+		
+		if (lenFromCache < lenFromFile) {	// there's more to copy from the file
+			lenFromFile -= lenFromCache;
+			lenRemainingInFile -= lenFromCache;	// since we moved pos
+			destPtr += lenFromCache;
+		} else {							// we're done
+#ifdef DEBUG_BUFFERS
+			printBuffer((byte *)ptr, len);
+#endif			
+			
+			return lenFromCache;			// how much we actually read
+		}		
+	}
+
 	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
+	
+	
+	synchronizePhysicalPos();	// we need to update our physical position
+	
+	if (lenFromFile <= MIN_READ_SIZE) {	// We load the cache in case the read is small enough
+		// This optimization is based on the principle that reading 1 byte is as expensive as 1000 bytes
+		uint32 lenToCopyToCache = MIN2((uint32)MIN_READ_SIZE, lenRemainingInFile); // at most remaining file size
+		
+		PSP_DEBUG_PRINT("filling cache with 0x%x bytes from physicalPos[0x%x]. cacheStart[0x%x], pos[0x%x], fileSize[0x%x]\n", lenToCopyToCache, _physicalPos, _cacheStartOffset, _pos, _fileSize);
+		
+		size_t ret = fread(_cache, 1, lenToCopyToCache, (FILE *)_handle);
+		if (ret != lenToCopyToCache) {
+			PSP_ERROR("in filling cache, failed to get 0x%x bytes. Only got 0x%x\n", lenToCopyToCache, ret);
+			_ferror = true;
+			clearerr((FILE *)_handle);
+		}
+		_cacheStartOffset = _physicalPos;
+		_inCache = true;
+		
+		_physicalPos += ret;
+		
+		PSP_DEBUG_PRINT("copying 0x%x bytes from cache to %p\n", lenFromFile, destPtr);
+		
+		// Copy to the destination buffer from cache
+		memcpy(destPtr, _cache, lenFromFile);
+		_pos += lenFromFile;
+		
+	} else {	// Too big for cache. No caching
+		PSP_DEBUG_PRINT("reading 0x%x bytes from file to %p. Pos[0x%x], physPos[0x%x]\n", lenFromFile, destPtr, _pos, _physicalPos);
+		size_t ret = fread(destPtr, 1, lenFromFile, (FILE *)_handle);
 
-	PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
+		_physicalPos += ret;	// Update pos
+		_pos = _physicalPos;
 
-	size_t ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
-
-	_pos += ret;	// Update pos
-
-	if (ret != len) {	// Check for eof
-		_feof = feof((FILE *)_handle);
-		if (!_feof) {	// It wasn't an eof. Must be an error
+		if (ret != lenFromFile) {	// error
+			PSP_ERROR("fread returned [0x%x] instead of len[0x%x]\n", ret, lenFromFile);
 			_ferror = true;
 			clearerr((FILE *)_handle);
-			_pos = ftell((FILE *)_handle);	// Update our position
-			_errorSource = 4;
-			PSP_ERROR("fread returned ret[%d] instead of len[%d]\n", ret, len);
+			_errorSource = 4;			
 		}
+		_inCache = false;
 	}
 
 	PowerMan.endCriticalSection();
 
-	return ret;
+#ifdef DEBUG_BUFFERS
+	printBuffer((byte *)ptr, len);
+#endif	
+		
+	return lenFromCache + lenFromFile;		// total of what was copied
 }
 
+// TODO: Test if seeking backwards/forwards has any effect on performance
+inline bool PSPIoStream::synchronizePhysicalPos() {
+	if (_pos != _physicalPos) {
+		if (fseek((FILE *)_handle, _pos - _physicalPos, SEEK_CUR) != 0)
+			return false;
+		_physicalPos = _pos;	
+	}
+	
+	return true;
+}
+
+inline bool PSPIoStream::isOffsetInCache(uint32 offset) {
+	if (_cacheStartOffset != -1 && 
+		offset >= (uint32)_cacheStartOffset && 
+		offset < (uint32)(_cacheStartOffset + CACHE_SIZE))
+		return true;
+	return false;
+}
+
 uint32 PSPIoStream::write(const void *ptr, uint32 len) {
 	DEBUG_ENTER_FUNC();
 	// Check if we can access the file
 	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 
-	PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
+	PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x]\n", _path.c_str(), len);
 
+	if (_ferror)
+		return 0;
+		
+	_eos = false;	// we can't have eos with write
+	synchronizePhysicalPos();
+	
 	size_t ret = fwrite(ptr, 1, len, (FILE *)_handle);
 
-	_pos += ret;
+	// If we're making the file bigger, adjust the size
+	if (_physicalPos + (int)ret > _fileSize)
+		_fileSize = _physicalPos + ret;
+	_physicalPos += ret;
+	_pos = _physicalPos;
+	_inCache = false;
+	_cacheStartOffset = -1;	// invalidate cache
 
 	if (ret != len) {	// Set error
 		_ferror = true;
 		clearerr((FILE *)_handle);
 		_pos = ftell((FILE *)_handle);	// Update pos
 		_errorSource = 5;
-		PSP_ERROR("fwrite returned[%d] instead of len[%d]\n", ret, len);
+		PSP_ERROR("fwrite returned[0x%x] instead of len[0x%x]\n", ret, len);
 	}
 
 	PowerMan.endCriticalSection();
@@ -224,7 +355,7 @@
 		_ferror = true;
 		clearerr((FILE *)_handle);
 		_errorSource = 6;
-		PSP_ERROR("fflush returned ret[%u]\n", ret);
+		PSP_ERROR("fflush returned ret[%d]\n", ret);
 	}
 
 	PowerMan.endCriticalSection();
@@ -286,6 +417,9 @@
 	// Resume our previous position
 	if (_handle > 0 && _pos > 0) {
 		ret = fseek((FILE *)_handle, _pos, SEEK_SET);
+		
+		_physicalPos = _pos;
+		_inCache = false;
 
 		if (ret != 0) {		// Check for problem
 			_errorSuspend = ResumeError;

Modified: scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.h
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.h	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/backends/fs/psp/psp-stream.h	2010-06-08 03:31:27 UTC (rev 49499)
@@ -35,25 +35,39 @@
  */
 class PSPIoStream : public StdioStream, public Suspendable {
 protected:
-	Common::String _path;			/* Need to maintain for reopening after suspend */
-	bool _writeMode;				/* "" */
-	int _pos;						/* "" */
-	mutable int _ferror;			/* Save file ferror */
-	mutable bool _feof;						/* and eof */
-
+	Common::String _path;
+	int _fileSize;
+	bool _writeMode;	// for resuming in the right mode
+	int _physicalPos;	// position in the real file
+	int _pos;			// position. Sometimes virtual
+	bool _inCache;		// whether we're in cache (virtual) mode
+	bool _eos;			// EOS flag
+	
 	enum {
 		SuspendError = 2,
 		ResumeError = 3
 	};
 
-	int _errorSuspend;
+	enum {
+		CACHE_SIZE = 1024,
+		MIN_READ_SIZE = 1024	// reading less than 1024 takes exactly the same time as 1024
+	};
+	
+	// For caching
+	char *_cache;
+	int _cacheStartOffset;		// starting offset of the cache. -1 when cache is invalid
+	
+	mutable int _ferror;		// file error state
+	int _errorSuspend;			// for debugging
 	mutable int _errorSource;
-
-	// Error checking
 	int _errorPos;
 	void * _errorHandle;
 	int _suspendCount;
 
+	bool synchronizePhysicalPos();		// synchronize the physical and virtual positions
+	bool isOffsetInCache(uint32 pos);	// check if an offset is found in cache
+	bool isCacheValid() { return _cacheStartOffset != -1; }
+	
 public:
 
 	/**

Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp	2010-06-08 03:03:03 UTC (rev 49498)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp	2010-06-08 03:31:27 UTC (rev 49499)
@@ -195,7 +195,6 @@
 	return
 		(f == OSystem::kFeatureFullscreenMode) ||
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
-		(f == OSystem::kFeatureAutoComputeDirtyRects) ||
 		(f == OSystem::kFeatureCursorHasPalette) ||
 		(f == OSystem::kFeatureIconifyWindow);
 }

Deleted: scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build
===================================================================
--- scummvm/trunk/backends/platform/android/README.build	2010-06-08 01:07:10 UTC (rev 49497)
+++ scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build	2010-06-08 03:31:27 UTC (rev 49499)
@@ -1,84 +0,0 @@
-Building the ScummVM Android port
-=================================
-
-You will need these things to build:
-1. Android EGL headers and library
-2. Android SDK
-3. An arm-android-eabi GCC toolchain
-
-In the example commands, we are going to build against the Android 1.5
-native ABI (but using the Android 1.6 SDK tools).  Other version
-combinations might/should be possible with a bit of tweaking.
-
-In detail:
-
-1. Android EGL headers and library
-
-You can build these from the full Android source, but it is far easier
-to just download the 3 Android EGL headers from here:
- http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tree;f=opengl/include/EGL;hb=HEAD
- (copy them to a directory called "EGL" somewhere)
-
-... and grab libEGL.so off an existing phone/emulator:
- adb pull /system/lib/libEGL.so /tmp
-
-2. Android SDK
-
-Download and install somewhere.
-
-3. arm-android-eabi GCC toolchain
-
-You have several choices for toolchains:
-
-- Use Google arm-eabi prebuilt toolchain.
-
-This is shipped with both the Android source release and Android NDK.
-The problem is that "arm-eabi-gcc" can't actually link anything
-successfully without extra command line flags.  To use this with the
-ScummVM configure/build environment you will need to create a family
-of shell wrapper scripts that convert "arm-android-eabi-foo" to
-"arm-eabi-foo -mandroid".
-
-For example, I use this script:
- #!/bin/sh
- exec arm-eabi-${0##*-} -mandroid -DANDROID "$@"
-
-... and create a family of symlinks/hardlinks pointing to it called
-arm-android-eabi-gcc, arm-android-eabi-g++, etc.  For tools that don't
-take a "-mandroid" argument - like arm-eabi-strip - I bypass the shell
-wrapper and just create an arm-android-eabi-strip symlink to the tool
-directly.
-
-- Build your own arm-android-eabi toolchain from GCC source.
-
-This is lots of fun.  I suggest my Android openembedded patches, see:
-  http://wiki.github.com/anguslees/openembedded-android/
-(You just need to have lots of disk space and type a few commands)
-If you get stuck, ask 
-
-Alternatively, do a websearch - there are several other cross-compile
-toolchains around.
-
-
-Building ScummVM
-================
-
- export ANDROID_SDK=<root of Android SDK>
-
- PATH=$ANDROID_SDK/platforms/android-1.6/tools:$ANDROID_SDK/tools:$PATH
- # You also want to ensure your arm-android-eabi toolchain is in your $PATH
-
- export ANDROID_TOP=<root of built Android source>
-
- EGL_INC="-I<location of EGL/ header directory>"
- EGL_LIBS="-L<location of libEGL.so>"
-
- CPPFLAGS="$EGL_INC" \
- LDFLAGS="-g $EGL_LIBS" \
- ./configure --backend=android --host=android --enable-zlib #and any other flags
- make scummvm.apk
-
-This will build a "monolithic" ScummVM package, with the engines
-statically linked in.  If you want to build separate engine packages,
-like on the market, add "--enable-plugins --default-dynamic" to
-configure and also make scummvm-engine-scumm.apk, etc.

Copied: scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build (from rev 49497, scummvm/trunk/backends/platform/android/README.build)
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build	                        (rev 0)
+++ scummvm/branches/gsoc2010-opengl/backends/platform/android/README.build	2010-06-08 03:31:27 UTC (rev 49499)
@@ -0,0 +1,84 @@
+Building the ScummVM Android port
+=================================
+
+You will need these things to build:
+1. Android EGL headers and library
+2. Android SDK
+3. An arm-android-eabi GCC toolchain
+
+In the example commands, we are going to build against the Android 1.5
+native ABI (but using the Android 1.6 SDK tools).  Other version
+combinations might/should be possible with a bit of tweaking.
+
+In detail:
+
+1. Android EGL headers and library
+
+You can build these from the full Android source, but it is far easier
+to just download the 3 Android EGL headers from here:
+ http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tree;f=opengl/include/EGL;hb=HEAD
+ (copy them to a directory called "EGL" somewhere)
+
+... and grab libEGL.so off an existing phone/emulator:
+ adb pull /system/lib/libEGL.so /tmp
+
+2. Android SDK
+
+Download and install somewhere.
+
+3. arm-android-eabi GCC toolchain
+
+You have several choices for toolchains:
+
+- Use Google arm-eabi prebuilt toolchain.
+
+This is shipped with both the Android source release and Android NDK.
+The problem is that "arm-eabi-gcc" can't actually link anything
+successfully without extra command line flags.  To use this with the
+ScummVM configure/build environment you will need to create a family
+of shell wrapper scripts that convert "arm-android-eabi-foo" to
+"arm-eabi-foo -mandroid".
+
+For example, I use this script:
+ #!/bin/sh
+ exec arm-eabi-${0##*-} -mandroid -DANDROID "$@"
+
+... and create a family of symlinks/hardlinks pointing to it called
+arm-android-eabi-gcc, arm-android-eabi-g++, etc.  For tools that don't
+take a "-mandroid" argument - like arm-eabi-strip - I bypass the shell
+wrapper and just create an arm-android-eabi-strip symlink to the tool
+directly.
+
+- Build your own arm-android-eabi toolchain from GCC source.
+
+This is lots of fun.  I suggest my Android openembedded patches, see:
+  http://wiki.github.com/anguslees/openembedded-android/
+(You just need to have lots of disk space and type a few commands)
+If you get stuck, ask 
+
+Alternatively, do a websearch - there are several other cross-compile
+toolchains around.
+
+
+Building ScummVM
+================
+
+ export ANDROID_SDK=<root of Android SDK>
+
+ PATH=$ANDROID_SDK/platforms/android-1.6/tools:$ANDROID_SDK/tools:$PATH
+ # You also want to ensure your arm-android-eabi toolchain is in your $PATH
+
+ export ANDROID_TOP=<root of built Android source>
+
+ EGL_INC="-I<location of EGL/ header directory>"
+ EGL_LIBS="-L<location of libEGL.so>"
+
+ CPPFLAGS="$EGL_INC" \
+ LDFLAGS="-g $EGL_LIBS" \
+ ./configure --backend=android --host=android --enable-zlib #and any other flags
+ make scummvm.apk
+
+This will build a "monolithic" ScummVM package, with the engines
+statically linked in.  If you want to build separate engine packages,
+like on the market, add "--enable-plugins --default-dynamic" to
+configure and also make scummvm-engine-scumm.apk, etc.

Deleted: scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp
===================================================================
--- scummvm/trunk/backends/platform/android/android.cpp	2010-06-08 01:07:10 UTC (rev 49497)
+++ scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp	2010-06-08 03:31:27 UTC (rev 49499)
@@ -1,1413 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "backends/base-backend.h"
-#include "base/main.h"
-#include "graphics/surface.h"
-
-#include "backends/platform/android/video.h"
-
-#if defined(ANDROID_BACKEND)
-
-#define ANDROID_VERSION_GE(major,minor) \
-  (ANDROID_MAJOR_VERSION > (major) || \
-   (ANDROID_MAJOR_VERSION == (major) && ANDROID_MINOR_VERSION >= (minor)))
-
-#include <jni.h>
-
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <EGL/egl.h>
-#include <android/log.h>
-
-#include "common/archive.h"
-#include "common/util.h"
-#include "common/rect.h"
-#include "common/queue.h"
-#include "common/mutex.h"
-#include "common/events.h"
-#include "common/config-manager.h"
-
-#include "backends/fs/posix/posix-fs-factory.h"
-#include "backends/keymapper/keymapper.h"
-#include "backends/saves/default/default-saves.h"
-#include "backends/timer/default/default-timer.h"
-#include "backends/plugins/posix/posix-provider.h"
-#include "sound/mixer_intern.h"
-
-#include "backends/platform/android/asset-archive.h"
-
-#undef LOG_TAG
-#define LOG_TAG "ScummVM"
-
-#if 0
-#define ENTER(args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, args)
-#else
-#define ENTER(args...) /**/
-#endif
-
-// Fix JNIEXPORT declaration to actually do something useful
-#undef JNIEXPORT
-#define JNIEXPORT __attribute__ ((visibility("default")))
-
-static JavaVM *cached_jvm;
-static jfieldID FID_Event_type;
-static jfieldID FID_Event_synthetic;
-static jfieldID FID_Event_kbd_keycode;
-static jfieldID FID_Event_kbd_ascii;
-static jfieldID FID_Event_kbd_flags;
-static jfieldID FID_Event_mouse_x;
-static jfieldID FID_Event_mouse_y;
-static jfieldID FID_Event_mouse_relative;
-static jfieldID FID_ScummVM_nativeScummVM;
-static jmethodID MID_Object_wait;
-
-JNIEnv* JNU_GetEnv() {
-	JNIEnv* env;
-	bool version_unsupported =
-		cached_jvm->GetEnv((void**)&env, JNI_VERSION_1_2);
-	assert(! version_unsupported);
-	return env;
-}
-
-static void JNU_ThrowByName(JNIEnv* env, const char* name, const char* msg) {
-	jclass cls = env->FindClass(name);
-	// if cls is NULL, an exception has already been thrown
-	if (cls != NULL)
-		env->ThrowNew(cls, msg);
-	env->DeleteLocalRef(cls);
-}
-
-// floating point.	use sparingly.
-template <class T>
-static inline T scalef(T in, float numerator, float denominator) {
-	return static_cast<float>(in) * numerator / denominator;
-}
-
-static inline GLfixed xdiv(int numerator, int denominator) {
-	assert(numerator < (1<<16));
-	return (numerator << 16) / denominator;
-}
-
-#ifdef DYNAMIC_MODULES
-class AndroidPluginProvider : public POSIXPluginProvider {
-protected:
-	virtual void addCustomDirectories(Common::FSList &dirs) const;
-};
-#endif
-
-
-#if 0
-#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
-static const char* getGlErrStr(GLenum error) {
-	switch (error) {
-	case GL_NO_ERROR:		   return "GL_NO_ERROR";
-	case GL_INVALID_ENUM:	   return "GL_INVALID_ENUM";
-	case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
-	case GL_STACK_OVERFLOW:	   return "GL_STACK_OVERFLOW";
-	case GL_STACK_UNDERFLOW:   return "GL_STACK_UNDERFLOW";
-	case GL_OUT_OF_MEMORY:	   return "GL_OUT_OF_MEMORY";
-	}
-
-	static char buf[40];
-	snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
-	return buf;
-}
-static void checkGlError(const char* file, int line) {
-	GLenum error = glGetError();
-	if (error != GL_NO_ERROR)
-		warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
-}
-#else
-#define CHECK_GL_ERROR() do {} while (false)
-#endif
-
-class OSystem_Android : public BaseBackend {
-private:
-	jobject _back_ptr;	// back pointer to (java) peer instance
-	jmethodID MID_displayMessageOnOSD;
-	jmethodID MID_setWindowCaption;
-	jmethodID MID_initBackend;
-	jmethodID MID_audioSampleRate;
-	jmethodID MID_showVirtualKeyboard;
-	jmethodID MID_getSysArchives;
-	jmethodID MID_getPluginDirectories;
-	jmethodID MID_setupScummVMSurface;
-	jmethodID MID_destroyScummVMSurface;
-
-	int _screen_changeid;
-	EGLDisplay _egl_display;
-	EGLSurface _egl_surface;
-	EGLint _egl_surface_width;
-	EGLint _egl_surface_height;
-
-	bool _force_redraw;
-
-	// Game layer
-	GLESPaletteTexture* _game_texture;
-	int _shake_offset;
-	bool _full_screen_dirty;
-	Common::Array<Common::Rect> _dirty_rects;
-
-	// Overlay layer
-	GLES4444Texture* _overlay_texture;
-	bool _show_overlay;
-
-	// Mouse layer
-	GLESPaletteATexture* _mouse_texture;
-	Common::Point _mouse_hotspot;
-	int _mouse_targetscale;
-	bool _show_mouse;
-	bool _use_mouse_palette;
-
-	Common::Queue<Common::Event> _event_queue;
-	MutexRef _event_queue_lock;
-
-	bool _timer_thread_exit;
-	pthread_t _timer_thread;
-	static void* timerThreadFunc(void* arg);
-
-	bool _virtkeybd_on;
-
-	Common::SaveFileManager *_savefile;
-	Audio::MixerImpl *_mixer;
-	Common::TimerManager *_timer;
-	FilesystemFactory *_fsFactory;
-	Common::Archive *_asset_archive;
-	timeval _startTime;
-
-	void setupScummVMSurface();
-	void destroyScummVMSurface();
-	void setupKeymapper();
-	void _setCursorPalette(const byte *colors, uint start, uint num);
-
-public:
-	OSystem_Android(jobject am);
-	virtual ~OSystem_Android();
-	bool initJavaHooks(JNIEnv* env, jobject self);
-
-	static OSystem_Android* fromJavaObject(JNIEnv* env, jobject obj);
-	virtual void initBackend();
-	void addPluginDirectories(Common::FSList &dirs) const;
-
-	virtual bool hasFeature(Feature f);
-	virtual void setFeatureState(Feature f, bool enable);
-	virtual bool getFeatureState(Feature f);
-	virtual const GraphicsMode *getSupportedGraphicsModes() const;
-	virtual int getDefaultGraphicsMode() const;
-	bool setGraphicsMode(const char *name);
-	virtual bool setGraphicsMode(int mode);
-	virtual int getGraphicsMode() const;
-	virtual void initSize(uint width, uint height,
-				  const Graphics::PixelFormat *format);
-	virtual int getScreenChangeID() const { return _screen_changeid; }
-	virtual int16 getHeight();
-	virtual int16 getWidth();
-	virtual void setPalette(const byte *colors, uint start, uint num);
-	virtual void grabPalette(byte *colors, uint start, uint num);
-	virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
-	virtual void updateScreen();
-	virtual Graphics::Surface *lockScreen();
-	virtual void unlockScreen();
-	virtual void setShakePos(int shakeOffset);
-	virtual void fillScreen(uint32 col);
-	virtual void setFocusRectangle(const Common::Rect& rect);
-	virtual void clearFocusRectangle();
-
-	virtual void showOverlay();
-	virtual void hideOverlay();
-	virtual void clearOverlay();
-	virtual void grabOverlay(OverlayColor *buf, int pitch);
-	virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
-	virtual int16 getOverlayHeight();
-	virtual int16 getOverlayWidth();
-	virtual Graphics::PixelFormat getOverlayFormat() const {
-		// RGBA 4444
-		Graphics::PixelFormat format;
-		format.bytesPerPixel = 2;
-		format.rLoss = 8 - 4;
-		format.gLoss = 8 - 4;
-		format.bLoss = 8 - 4;
-		format.aLoss = 8 - 4;
-		format.rShift = 3*4;
-		format.gShift = 2*4;
-		format.bShift = 1*4;
-		format.aShift = 0*4;
-		return format;
-	}
-
-	virtual bool showMouse(bool visible);
-
-	virtual void warpMouse(int x, int y);
-	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
-	virtual void setCursorPalette(const byte *colors, uint start, uint num);
-	virtual void disableCursorPalette(bool disable);
-
-	virtual bool pollEvent(Common::Event &event);
-	void pushEvent(const Common::Event& event);
-	virtual uint32 getMillis();
-	virtual void delayMillis(uint msecs);
-
-	virtual MutexRef createMutex(void);
-	virtual void lockMutex(MutexRef mutex);
-	virtual void unlockMutex(MutexRef mutex);
-	virtual void deleteMutex(MutexRef mutex);
-
-	virtual void quit();
-
-	virtual void setWindowCaption(const char *caption);
-	virtual void displayMessageOnOSD(const char *msg);
-	virtual void showVirtualKeyboard(bool enable);
-
-	virtual Common::SaveFileManager *getSavefileManager();
-	virtual Audio::Mixer *getMixer();
-	virtual void getTimeAndDate(TimeDate &t) const;
-	virtual Common::TimerManager *getTimerManager();
-	virtual FilesystemFactory *getFilesystemFactory();
-	virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
-};
-
-OSystem_Android::OSystem_Android(jobject am)
-	: _back_ptr(0),
-	  _egl_display(EGL_NO_DISPLAY),
-	  _egl_surface(EGL_NO_SURFACE),
-	  _screen_changeid(0),
-	  _force_redraw(false),
-	  _game_texture(NULL),
-	  _overlay_texture(NULL),
-	  _mouse_texture(NULL),
-	  _use_mouse_palette(false),
-	  _show_mouse(false),
-	  _show_overlay(false),
-	  _savefile(0),
-	  _mixer(0),
-	  _timer(0),
-	  _fsFactory(new POSIXFilesystemFactory()),
-	  _asset_archive(new AndroidAssetArchive(am)),
-	  _shake_offset(0),
-	  _full_screen_dirty(false),
-	  _event_queue_lock(createMutex()) {
-}
-
-OSystem_Android::~OSystem_Android() {
-	ENTER("~OSystem_Android()");
-	delete _game_texture;
-	delete _overlay_texture;
-	delete _mouse_texture;
-	destroyScummVMSurface();
-	JNIEnv* env = JNU_GetEnv();
-	//env->DeleteWeakGlobalRef(_back_ptr);
-	env->DeleteGlobalRef(_back_ptr);
-	delete _savefile;
-	delete _mixer;
-	delete _timer;
-	delete _fsFactory;
-	delete _asset_archive;
-	deleteMutex(_event_queue_lock);
-}
-
-OSystem_Android* OSystem_Android::fromJavaObject(JNIEnv* env, jobject obj) {
-	jlong peer = env->GetLongField(obj, FID_ScummVM_nativeScummVM);
-	return (OSystem_Android*)peer;
-}
-
-bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
-	// weak global ref to allow class to be unloaded
-	// ... except dalvik doesn't implement NewWeakGlobalRef (yet)
-	//_back_ptr = env->NewWeakGlobalRef(self);
-	_back_ptr = env->NewGlobalRef(self);
-
-	jclass cls = env->GetObjectClass(_back_ptr);
-
-#define FIND_METHOD(name, signature) do {						\
-		MID_ ## name = env->GetMethodID(cls, #name, signature); \
-		if (MID_ ## name == NULL)								\
-			return false;										\
-	} while (0)
-
-	FIND_METHOD(setWindowCaption, "(Ljava/lang/String;)V");
-	FIND_METHOD(displayMessageOnOSD, "(Ljava/lang/String;)V");
-	FIND_METHOD(initBackend, "()V");
-	FIND_METHOD(audioSampleRate, "()I");
-	FIND_METHOD(showVirtualKeyboard, "(Z)V");
-	FIND_METHOD(getSysArchives, "()[Ljava/lang/String;");
-	FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
-	FIND_METHOD(setupScummVMSurface, "()V");
-	FIND_METHOD(destroyScummVMSurface, "()V");
-
-#undef FIND_METHOD
-
-	return true;
-}
-
-static void ScummVM_create(JNIEnv* env, jobject self, jobject am) {
-	OSystem_Android* cpp_obj = new OSystem_Android(am);
-	if (!cpp_obj->initJavaHooks(env, self))
-		// Exception already thrown by initJavaHooks
-		return;
-
-	env->SetLongField(self, FID_ScummVM_nativeScummVM, (jlong)cpp_obj);
-
-#ifdef DYNAMIC_MODULES
-	PluginManager::instance().addPluginProvider(new AndroidPluginProvider());
-#endif
-}
-
-static void ScummVM_nativeDestroy(JNIEnv* env, jobject self) {
-	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
-	delete cpp_obj;
-}
-
-static void ScummVM_audioMixCallback(JNIEnv* env, jobject self,
-									 jbyteArray jbuf) {
-	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
-	jsize len = env->GetArrayLength(jbuf);
-	jbyte* buf = env->GetByteArrayElements(jbuf, NULL);
-	if (buf == NULL) {
-		warning("Unable to get Java audio byte array. Skipping.");
-		return;
-	}
-	Audio::MixerImpl* mixer =
-		static_cast<Audio::MixerImpl*>(cpp_obj->getMixer());
-	assert(mixer);
-	mixer->mixCallback(reinterpret_cast<byte*>(buf), len);
-	env->ReleaseByteArrayElements(jbuf, buf, 0);
-}
-
-static void ScummVM_setConfManInt(JNIEnv* env, jclass cls,
-				  jstring key_obj, jint value) {
-	ENTER("setConfManInt(%p, %d)", key_obj, (int)value);
-	const char* key = env->GetStringUTFChars(key_obj, NULL);
-	if (key == NULL)
-		return;
-	ConfMan.setInt(key, value);
-	env->ReleaseStringUTFChars(key_obj, key);
-}
-
-static void ScummVM_setConfManString(JNIEnv* env, jclass cls, jstring key_obj,
-					 jstring value_obj) {
-	ENTER("setConfManStr(%p, %p)", key_obj, value_obj);
-	const char* key = env->GetStringUTFChars(key_obj, NULL);
-	if (key == NULL)
-		return;
-	const char* value = env->GetStringUTFChars(value_obj, NULL);
-	if (value == NULL) {
-		env->ReleaseStringUTFChars(key_obj, key);
-		return;
-	}
-	ConfMan.set(key, value);
-	env->ReleaseStringUTFChars(value_obj, value);
-	env->ReleaseStringUTFChars(key_obj, key);
-}
-
-void* OSystem_Android::timerThreadFunc(void* arg) {
-	OSystem_Android* system = (OSystem_Android*)arg;
-	DefaultTimerManager* timer = (DefaultTimerManager*)(system->_timer);
-
-	struct timespec tv;
-	tv.tv_sec = 0;
-	tv.tv_nsec = 100 * 1000 * 1000;	// 100ms
-
-	while (!system->_timer_thread_exit) {
-		timer->handler();
-		nanosleep(&tv, NULL);
-	}
-
-	return NULL;
-}
-
-void OSystem_Android::initBackend() {
-	ENTER("initBackend()");
-	JNIEnv* env = JNU_GetEnv();
-
-	ConfMan.setInt("autosave_period", 0);
-	ConfMan.setInt("FM_medium_quality", true);
-
-	// must happen before creating TimerManager to avoid race in
-	// creating EventManager
-	setupKeymapper();
-
-	// BUG: "transient" ConfMan settings get nuked by the options
-	// screen.	Passing the savepath in this way makes it stick
-	// (via ConfMan.registerDefault)
-	_savefile = new DefaultSaveFileManager(ConfMan.get("savepath"));
-	_timer = new DefaultTimerManager();
-
-	gettimeofday(&_startTime, NULL);
-
-	jint sample_rate = env->CallIntMethod(_back_ptr, MID_audioSampleRate);
-	if (env->ExceptionCheck()) {
-		warning("Error finding audio sample rate - assuming 11025HZ");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-		sample_rate = 11025;
-	}
-	_mixer = new Audio::MixerImpl(this, sample_rate);
-	_mixer->setReady(true);
-
-	env->CallVoidMethod(_back_ptr, MID_initBackend);
-	if (env->ExceptionCheck()) {
-		error("Error in Java initBackend");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-	}
-
-	_timer_thread_exit = false;
-	pthread_create(&_timer_thread, NULL, timerThreadFunc, this);
-
-	OSystem::initBackend();
-
-	setupScummVMSurface();
-}
-
-void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
-	ENTER("OSystem_Android::addPluginDirectories()");
-	JNIEnv* env = JNU_GetEnv();
-
-	jobjectArray array =
-		(jobjectArray)env->CallObjectMethod(_back_ptr, MID_getPluginDirectories);
-	if (env->ExceptionCheck()) {
-		warning("Error finding plugin directories");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-		return;
-	}
-
-	jsize size = env->GetArrayLength(array);
-	for (jsize i = 0; i < size; ++i) {
-		jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
-		if (path_obj == NULL)
-			continue;
-		const char* path = env->GetStringUTFChars(path_obj, NULL);
-		if (path == NULL) {
-			warning("Error getting string characters from plugin directory");
-			env->ExceptionClear();
-			env->DeleteLocalRef(path_obj);
-			continue;
-		}
-		dirs.push_back(Common::FSNode(path));
-		env->ReleaseStringUTFChars(path_obj, path);
-		env->DeleteLocalRef(path_obj);
-	}
-}
-
-bool OSystem_Android::hasFeature(Feature f) {
-	return (f == kFeatureCursorHasPalette ||
-		f == kFeatureVirtualKeyboard ||
-		f == kFeatureOverlaySupportsAlpha);
-}
-
-void OSystem_Android::setFeatureState(Feature f, bool enable) {
-	ENTER("setFeatureState(%d, %d)", f, enable);
-	switch (f) {
-	case kFeatureVirtualKeyboard:
-		_virtkeybd_on = enable;
-		showVirtualKeyboard(enable);
-		break;
-	default:
-		break;
-	}
-}
-
-bool OSystem_Android::getFeatureState(Feature f) {
-	switch (f) {
-	case kFeatureVirtualKeyboard:
-		return _virtkeybd_on;
-	default:
-		return false;
-	}
-}
-
-const OSystem::GraphicsMode* OSystem_Android::getSupportedGraphicsModes() const {
-	static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
-		{"default", "Default", 1},
-		{0, 0, 0},
-	};
-	return s_supportedGraphicsModes;
-}
-
-
-int OSystem_Android::getDefaultGraphicsMode() const {
-	return 1;
-}
-
-bool OSystem_Android::setGraphicsMode(const char *mode) {
-	ENTER("setGraphicsMode(%s)", mode);
-	return true;
-}
-
-bool OSystem_Android::setGraphicsMode(int mode) {
-	ENTER("setGraphicsMode(%d)", mode);
-	return true;
-}
-
-int OSystem_Android::getGraphicsMode() const {
-	return 1;
-}
-
-void OSystem_Android::setupScummVMSurface() {
-	JNIEnv* env = JNU_GetEnv();
-	env->CallVoidMethod(_back_ptr, MID_setupScummVMSurface);
-	if (env->ExceptionCheck())
-		return;
-
-	// EGL set up with a new surface.  Initialise OpenGLES context.
-
-	_egl_display = eglGetCurrentDisplay();
-	_egl_surface = eglGetCurrentSurface(EGL_DRAW);
-
-	static bool log_version = true;
-	if (log_version) {
-		__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
-							"Using EGL %s (%s); GL %s/%s (%s)",
-							eglQueryString(_egl_display, EGL_VERSION),
-							eglQueryString(_egl_display, EGL_VENDOR),
-							glGetString(GL_VERSION),
-							glGetString(GL_RENDERER),
-							glGetString(GL_VENDOR));
-		log_version = false;		// only log this once
-	}
-
-	GLESTexture::initGLExtensions();
-
-	if (!eglQuerySurface(_egl_display, _egl_surface,
-						 EGL_WIDTH, &_egl_surface_width) ||
-		!eglQuerySurface(_egl_display, _egl_surface,
-						 EGL_HEIGHT, &_egl_surface_height)) {
-		JNU_ThrowByName(env, "java/lang/RuntimeException",
-						"Error fetching EGL surface width/height");
-		return;
-	}
-	__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
-						"New surface is %dx%d",
-						_egl_surface_width, _egl_surface_height);
-
-	CHECK_GL_ERROR();
-
-	// Turn off anything that looks like 3D ;)
-	glDisable(GL_CULL_FACE);
-	glDisable(GL_DEPTH_TEST);
-	glDisable(GL_LIGHTING);
-	glDisable(GL_FOG);
-	glDisable(GL_DITHER);
-	glShadeModel(GL_FLAT);
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
-
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-	glEnable(GL_TEXTURE_2D);
-
-	if (!_game_texture)
-		_game_texture = new GLESPaletteTexture();
-	else
-		_game_texture->reinitGL();
-
-	if (!_overlay_texture)
-		_overlay_texture = new GLES4444Texture();
-	else
-		_overlay_texture->reinitGL();
-
-	if (!_mouse_texture)
-		_mouse_texture = new GLESPaletteATexture();
-	else
-		_mouse_texture->reinitGL();
-
-	glViewport(0, 0, _egl_surface_width, _egl_surface_height);
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
-
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-
-	CHECK_GL_ERROR();
-
-	_force_redraw = true;
-}
-
-void OSystem_Android::destroyScummVMSurface() {
-	_egl_surface = EGL_NO_SURFACE;
-	JNIEnv* env = JNU_GetEnv();
-	env->CallVoidMethod(_back_ptr, MID_destroyScummVMSurface);
-	// Can't use OpenGLES functions after this
-}
-
-void OSystem_Android::initSize(uint width, uint height,
-							   const Graphics::PixelFormat *format) {
-	ENTER("initSize(%d,%d,%p)", width, height, format);
-
-	_game_texture->allocBuffer(width, height);
-
-	// Cap at 320x200 or the ScummVM themes abort :/
-	GLuint overlay_width = MIN(_egl_surface_width, 320);
-	GLuint overlay_height = MIN(_egl_surface_height, 200);
-	_overlay_texture->allocBuffer(overlay_width, overlay_height);
-
-	// Don't know mouse size yet - it gets reallocated in
-	// setMouseCursor.	We need the palette allocated before
-	// setMouseCursor however, so just take a guess at the desired
-	// size (it's small).
-	_mouse_texture->allocBuffer(20, 20);
-}
-
-int16 OSystem_Android::getHeight() {
-	return _game_texture->height();
-}
-
-int16 OSystem_Android::getWidth() {
-	return _game_texture->width();
-}
-
-void OSystem_Android::setPalette(const byte* colors, uint start, uint num) {
-		ENTER("setPalette(%p, %u, %u)", colors, start, num);
-
-	if (!_use_mouse_palette)
-		_setCursorPalette(colors, start, num);
-
-	byte* palette = _game_texture->palette() + start*3;
-	do {
-		for (int i = 0; i < 3; ++i)
-			palette[i] = colors[i];
-		palette += 3;
-		colors += 4;
-	} while (--num);
-}
-
-void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
-	ENTER("grabPalette(%p, %u, %u)", colors, start, num);
-	const byte* palette = _game_texture->palette_const() + start*3;
-	do {
-		for (int i = 0; i < 3; ++i)
-			colors[i] = palette[i];
-		colors[3] = 0xff;  // alpha
-
-		palette += 3;
-		colors += 4;
-	} while (--num);
-}
-
-void OSystem_Android::copyRectToScreen(const byte *buf, int pitch,
-					   int x, int y, int w, int h) {
-	ENTER("copyRectToScreen(%p, %d, %d, %d, %d, %d)",
-		  buf, pitch, x, y, w, h);
-
-	_game_texture->updateBuffer(x, y, w, h, buf, pitch);
-}
-
-void OSystem_Android::updateScreen() {
-	//ENTER("updateScreen()");
-
-	if (!_force_redraw &&
-		!_game_texture->dirty() &&
-		!_overlay_texture->dirty() &&
-		!_mouse_texture->dirty())
-		return;
-
-	_force_redraw = false;
-
-	glPushMatrix();
-
-	if (_shake_offset != 0) {
-		// This is the only case where _game_texture doesn't
-		// cover the entire screen.
-		glClearColorx(0, 0, 0, 1 << 16);
-		glClear(GL_COLOR_BUFFER_BIT);
-
-		// Move everything up by _shake_offset (game) pixels
-		glTranslatex(0, -_shake_offset << 16, 0);
-	}
-
-	_game_texture->drawTexture(0, 0,
-				   _egl_surface_width, _egl_surface_height);
-
-	CHECK_GL_ERROR();
-
-	if (_show_overlay) {
-		_overlay_texture->drawTexture(0, 0,
-						  _egl_surface_width,
-						  _egl_surface_height);
-		CHECK_GL_ERROR();
-	}
-
-	if (_show_mouse) {
-		glPushMatrix();
-
-		glTranslatex(-_mouse_hotspot.x << 16,
-				 -_mouse_hotspot.y << 16,
-				 0);
-
-		// Scale up ScummVM -> OpenGL (pixel) coordinates
-		int texwidth, texheight;
-		if (_show_overlay) {
-			texwidth = getOverlayWidth();
-			texheight = getOverlayHeight();
-		} else {
-			texwidth = getWidth();
-			texheight = getHeight();
-		}
-		glScalex(xdiv(_egl_surface_width, texwidth),
-			 xdiv(_egl_surface_height, texheight),
-			 1 << 16);
-
-		// Note the extra half texel to position the mouse in
-		// the middle of the x,y square:
-		const Common::Point& mouse = getEventManager()->getMousePos();
-		glTranslatex((mouse.x << 16) | 1 << 15,
-					 (mouse.y << 16) | 1 << 15, 0);
-
-		// Mouse targetscale just seems to make the cursor way
-		// too big :/
-		//glScalex(_mouse_targetscale << 16, _mouse_targetscale << 16,
-		//	 1 << 16);
-
-		_mouse_texture->drawTexture();
-
-		glPopMatrix();
-	}
-
-	glPopMatrix();
-
-	CHECK_GL_ERROR();
-
-	if (!eglSwapBuffers(_egl_display, _egl_surface)) {
-		EGLint error = eglGetError();
-		warning("eglSwapBuffers exited with error 0x%x", error);
-		// Some errors mean we need to reinit GL
-		if (error == EGL_CONTEXT_LOST) {
-			destroyScummVMSurface();
-			setupScummVMSurface();
-		}
-	}
-}
-
-Graphics::Surface *OSystem_Android::lockScreen() {
-	ENTER("lockScreen()");
-	Graphics::Surface* surface = _game_texture->surface();
-	assert(surface->pixels);
-	return surface;
-}
-
-void OSystem_Android::unlockScreen() {
-	ENTER("unlockScreen()");
-	assert(_game_texture->dirty());
-}
-
-void OSystem_Android::setShakePos(int shake_offset) {
-	ENTER("setShakePos(%d)", shake_offset);
-	if (_shake_offset != shake_offset) {
-		_shake_offset = shake_offset;
-		_force_redraw = true;
-	}
-}
-
-void OSystem_Android::fillScreen(uint32 col) {
-	ENTER("fillScreen(%u)", col);
-	assert(col < 256);
-	_game_texture->fillBuffer(col);
-}
-
-void OSystem_Android::setFocusRectangle(const Common::Rect& rect) {
-	ENTER("setFocusRectangle(%d,%d,%d,%d)",
-		  rect.left, rect.top, rect.right, rect.bottom);
-#if 0
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrthof(rect.left, rect.right, rect.top, rect.bottom, 0, 1);
-	glMatrixMode(GL_MODELVIEW);
-
-	_force_redraw = true;
-#endif
-}
-
-void OSystem_Android::clearFocusRectangle() {
-	ENTER("clearFocusRectangle()");
-#if 0
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
-	glMatrixMode(GL_MODELVIEW);
-
-	_force_redraw = true;
-#endif
-}
-
-void OSystem_Android::showOverlay() {
-	ENTER("showOverlay()");
-	_show_overlay = true;
-	_force_redraw = true;
-}
-
-void OSystem_Android::hideOverlay() {
-	ENTER("hideOverlay()");
-	_show_overlay = false;
-	_force_redraw = true;
-}
-
-void OSystem_Android::clearOverlay() {
-	ENTER("clearOverlay()");
-	_overlay_texture->fillBuffer(0);
-}
-
-void OSystem_Android::grabOverlay(OverlayColor *buf, int pitch) {
-	ENTER("grabOverlay(%p, %d)", buf, pitch);
-	// We support overlay alpha blending, so the pixel data here
-	// shouldn't actually be used.	Let's fill it with zeros, I'm sure
-	// it will be fine...
-	const Graphics::Surface* surface = _overlay_texture->surface_const();
-	assert(surface->bytesPerPixel == sizeof(buf[0]));
-	int h = surface->h;
-	do {
-		memset(buf, 0, surface->w * sizeof(buf[0]));
-		buf += pitch;  // This 'pitch' is pixels not bytes
-	} while (--h);
-}
-
-void OSystem_Android::copyRectToOverlay(const OverlayColor *buf, int pitch,
-					int x, int y, int w, int h) {
-	ENTER("copyRectToOverlay(%p, %d, %d, %d, %d, %d)",
-		 buf, pitch, x, y, w, h);
-	const Graphics::Surface* surface = _overlay_texture->surface_const();
-	assert(surface->bytesPerPixel == sizeof(buf[0]));
-
-	// This 'pitch' is pixels not bytes
-	_overlay_texture->updateBuffer(x, y, w, h, buf, pitch * sizeof(buf[0]));
-}
-
-int16 OSystem_Android::getOverlayHeight() {
-	return _overlay_texture->height();
-}
-
-int16 OSystem_Android::getOverlayWidth() {
-	return _overlay_texture->width();
-}
-
-bool OSystem_Android::showMouse(bool visible) {
-	ENTER("showMouse(%d)", visible);
-	_show_mouse = visible;
-	return true;
-}
-
-void OSystem_Android::warpMouse(int x, int y) {
-	ENTER("warpMouse(%d, %d)", x, y);
-	// We use only the eventmanager's idea of the current mouse
-	// position, so there is nothing extra to do here.
-}
-
-void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
-					 int hotspotX, int hotspotY,
-					 uint32 keycolor, int cursorTargetScale,
-					 const Graphics::PixelFormat *format) {
-	ENTER("setMouseCursor(%p, %u, %u, %d, %d, %d, %d, %p)",
-		  buf, w, h, hotspotX, hotspotY, (int)keycolor, cursorTargetScale,
-		  format);
-
-	assert(keycolor < 256);
-
-	_mouse_texture->allocBuffer(w, h);
-
-	// Update palette alpha based on keycolor
-	byte* palette = _mouse_texture->palette();
-	int i = 256;
-	do {
-		palette[3] = 0xff;
-		palette += 4;
-	} while (--i);
-	palette = _mouse_texture->palette();
-	palette[keycolor*4 + 3] = 0x00;
-	_mouse_texture->updateBuffer(0, 0, w, h, buf, w);
-
-	_mouse_hotspot = Common::Point(hotspotX, hotspotY);
-	_mouse_targetscale = cursorTargetScale;
-}
-
-void OSystem_Android::_setCursorPalette(const byte *colors,
-					uint start, uint num) {
-	byte* palette = _mouse_texture->palette() + start*4;
-	do {
-		for (int i = 0; i < 3; ++i)
-			palette[i] = colors[i];
-		// Leave alpha untouched to preserve keycolor
-
-		palette += 4;
-		colors += 4;
-	} while (--num);
-}
-
-void OSystem_Android::setCursorPalette(const byte *colors,
-					   uint start, uint num) {
-	ENTER("setCursorPalette(%p, %u, %u)", colors, start, num);
-	_setCursorPalette(colors, start, num);
-	_use_mouse_palette = true;
-}
-
-void OSystem_Android::disableCursorPalette(bool disable) {
-	ENTER("disableCursorPalette(%d)", disable);
-	_use_mouse_palette = !disable;
-}
-
-void OSystem_Android::setupKeymapper() {
-#ifdef ENABLE_KEYMAPPER
-	using namespace Common;
-
-	Keymapper *mapper = getEventManager()->getKeymapper();
-
-	HardwareKeySet *keySet = new HardwareKeySet();
-	keySet->addHardwareKey(
-		new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
-				kTriggerLeftKeyType,
-				kVirtualKeyboardActionType));
-	mapper->registerHardwareKeySet(keySet);
-
-	Keymap *globalMap = new Keymap("global");
-	Action *act;
-
-	act = new Action(globalMap, "VIRT", "Display keyboard",
-			 kVirtualKeyboardActionType);
-	act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
-
-	mapper->addGlobalKeymap(globalMap);
-
-	mapper->pushKeymap("global");
-#endif
-}
-
-bool OSystem_Android::pollEvent(Common::Event &event) {
-	//ENTER("pollEvent()");
-	lockMutex(_event_queue_lock);
-	if (_event_queue.empty()) {
-		unlockMutex(_event_queue_lock);
-		return false;
-	}
-	event = _event_queue.pop();
-	unlockMutex(_event_queue_lock);
-
-	switch (event.type) {
-	case Common::EVENT_MOUSEMOVE:
-		// TODO: only dirty/redraw move bounds
-		_force_redraw = true;
-		// fallthrough
-	case Common::EVENT_LBUTTONDOWN:
-	case Common::EVENT_LBUTTONUP:
-	case Common::EVENT_RBUTTONDOWN:
-	case Common::EVENT_RBUTTONUP:
-	case Common::EVENT_WHEELUP:
-	case Common::EVENT_WHEELDOWN:
-	case Common::EVENT_MBUTTONDOWN:
-	case Common::EVENT_MBUTTONUP: {
-		if (event.kbd.flags == 1) { // relative mouse hack
-			// Relative (trackball) mouse hack.
-			const Common::Point& mouse_pos =
-				getEventManager()->getMousePos();
-			event.mouse.x += mouse_pos.x;
-			event.mouse.y += mouse_pos.y;
-			event.mouse.x = CLIP(event.mouse.x, (int16)0, _show_overlay ?
-								 getOverlayWidth() : getWidth());
-			event.mouse.y = CLIP(event.mouse.y, (int16)0, _show_overlay ?
-								 getOverlayHeight() : getHeight());
-		} else {
-			// Touchscreen events need to be converted
-			// from device to game coords first.
-			const GLESTexture* tex = _show_overlay
-				? static_cast<GLESTexture*>(_overlay_texture)
-				: static_cast<GLESTexture*>(_game_texture);
-			event.mouse.x = scalef(event.mouse.x, tex->width(),
-								   _egl_surface_width);
-			event.mouse.y = scalef(event.mouse.y, tex->height(),
-								   _egl_surface_height);
-			event.mouse.x -= _shake_offset;
-		}
-		break;
-	}
-	case Common::EVENT_SCREEN_CHANGED:
-		debug("EVENT_SCREEN_CHANGED");
-		_screen_changeid++;
-		destroyScummVMSurface();
-		setupScummVMSurface();
-		break;
-	default:
-		break;
-	}
-
-	return true;
-}
-
-void OSystem_Android::pushEvent(const Common::Event& event) {
-	lockMutex(_event_queue_lock);
-
-	// Try to combine multiple queued mouse move events
-	if (event.type == Common::EVENT_MOUSEMOVE &&
-		!_event_queue.empty() &&
-		_event_queue.back().type == Common::EVENT_MOUSEMOVE) {
-	  Common::Event tail = _event_queue.back();
-	  if (event.kbd.flags) {
-		// relative movement hack
-		tail.mouse.x += event.mouse.x;
-		tail.mouse.y += event.mouse.y;
-	  } else {
-		// absolute position
-		tail.kbd.flags = 0;	 // clear relative flag
-		tail.mouse.x = event.mouse.x;
-		tail.mouse.y = event.mouse.y;
-	  }
-	}
-	else
-	  _event_queue.push(event);
-
-	unlockMutex(_event_queue_lock);
-}
-
-static void ScummVM_pushEvent(JNIEnv* env, jobject self, jobject java_event) {
-	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
-
-	Common::Event event;
-	event.type = (Common::EventType)env->GetIntField(java_event,
-							 FID_Event_type);
-	event.synthetic =
-		env->GetBooleanField(java_event, FID_Event_synthetic);
-
-	switch (event.type) {
-	case Common::EVENT_KEYDOWN:
-	case Common::EVENT_KEYUP:
-		event.kbd.keycode = (Common::KeyCode)env->GetIntField(
-			java_event, FID_Event_kbd_keycode);
-		event.kbd.ascii = static_cast<int>(env->GetIntField(
-			java_event, FID_Event_kbd_ascii));
-		event.kbd.flags = static_cast<int>(env->GetIntField(
-			java_event, FID_Event_kbd_flags));
-		break;
-	case Common::EVENT_MOUSEMOVE:
-	case Common::EVENT_LBUTTONDOWN:
-	case Common::EVENT_LBUTTONUP:
-	case Common::EVENT_RBUTTONDOWN:
-	case Common::EVENT_RBUTTONUP:
-	case Common::EVENT_WHEELUP:
-	case Common::EVENT_WHEELDOWN:
-	case Common::EVENT_MBUTTONDOWN:
-	case Common::EVENT_MBUTTONUP:
-		event.mouse.x =
-			env->GetIntField(java_event, FID_Event_mouse_x);
-		event.mouse.y =
-			env->GetIntField(java_event, FID_Event_mouse_y);
-		// This is a terrible hack.	 We stash "relativeness"
-		// in the kbd.flags field until pollEvent() can work
-		// it out.
-		event.kbd.flags = env->GetBooleanField(
-			java_event, FID_Event_mouse_relative) ? 1 : 0;
-		break;
-	default:
-		break;
-	}
-
-	cpp_obj->pushEvent(event);
-}
-
-uint32 OSystem_Android::getMillis() {
-	timeval curTime;
-	gettimeofday(&curTime, NULL);
-	return (uint32)(((curTime.tv_sec - _startTime.tv_sec) * 1000) + \
-			((curTime.tv_usec - _startTime.tv_usec) / 1000));
-}
-
-void OSystem_Android::delayMillis(uint msecs) {
-	usleep(msecs * 1000);
-}
-
-OSystem::MutexRef OSystem_Android::createMutex() {
-	pthread_mutexattr_t attr;
-	pthread_mutexattr_init(&attr);
-	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-
-	pthread_mutex_t *mutex = new pthread_mutex_t;
-	if (pthread_mutex_init(mutex, &attr) != 0) {
-		warning("pthread_mutex_init() failed!");
-		delete mutex;
-		return NULL;
-	}
-	return (MutexRef)mutex;
-}
-
-void OSystem_Android::lockMutex(MutexRef mutex) {
-	if (pthread_mutex_lock((pthread_mutex_t*)mutex) != 0)
-		warning("pthread_mutex_lock() failed!");
-}
-
-void OSystem_Android::unlockMutex(MutexRef mutex) {
-	if (pthread_mutex_unlock((pthread_mutex_t*)mutex) != 0)
-		warning("pthread_mutex_unlock() failed!");
-}
-
-void OSystem_Android::deleteMutex(MutexRef mutex) {
-	pthread_mutex_t* m = (pthread_mutex_t*)mutex;
-	if (pthread_mutex_destroy(m) != 0)
-		warning("pthread_mutex_destroy() failed!");
-	else
-		delete m;
-}
-
-void OSystem_Android::quit() {
-	ENTER("quit()");
-
-	_timer_thread_exit = true;
-	pthread_join(_timer_thread, NULL);
-}
-
-void OSystem_Android::setWindowCaption(const char *caption) {
-	ENTER("setWindowCaption(%s)", caption);
-	JNIEnv* env = JNU_GetEnv();
-	jstring java_caption = env->NewStringUTF(caption);
-	env->CallVoidMethod(_back_ptr, MID_setWindowCaption, java_caption);
-	if (env->ExceptionCheck()) {
-		warning("Failed to set window caption");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-	}
-	env->DeleteLocalRef(java_caption);
-}
-
-void OSystem_Android::displayMessageOnOSD(const char *msg) {
-	ENTER("displayMessageOnOSD(%s)", msg);
-	JNIEnv* env = JNU_GetEnv();
-	jstring java_msg = env->NewStringUTF(msg);
-	env->CallVoidMethod(_back_ptr, MID_displayMessageOnOSD, java_msg);
-	if (env->ExceptionCheck()) {
-		warning("Failed to display OSD message");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-	}
-	env->DeleteLocalRef(java_msg);
-}
-
-void OSystem_Android::showVirtualKeyboard(bool enable) {
-	ENTER("showVirtualKeyboard(%d)", enable);
-	JNIEnv* env = JNU_GetEnv();
-	env->CallVoidMethod(_back_ptr, MID_showVirtualKeyboard, enable);
-	if (env->ExceptionCheck()) {
-		error("Error trying to show virtual keyboard");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-	}
-}
-
-Common::SaveFileManager *OSystem_Android::getSavefileManager() {
-	assert(_savefile);
-	return _savefile;
-}
-
-Audio::Mixer *OSystem_Android::getMixer() {
-	assert(_mixer);
-	return _mixer;
-}
-
-Common::TimerManager *OSystem_Android::getTimerManager() {
-	assert(_timer);
-	return _timer;
-}
-
-void OSystem_Android::getTimeAndDate(TimeDate &td) const {
-	struct tm tm;
-	const time_t curTime = time(NULL);
-	localtime_r(&curTime, &tm);
-	td.tm_sec = tm.tm_sec;
-	td.tm_min = tm.tm_min;
-	td.tm_hour = tm.tm_hour;
-	td.tm_mday = tm.tm_mday;
-	td.tm_mon = tm.tm_mon;
-	td.tm_year = tm.tm_year;
-}
-
-FilesystemFactory *OSystem_Android::getFilesystemFactory() {
-	return _fsFactory;
-}
-
-void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s,
-						int priority) {
-	s.add("ASSET", _asset_archive, priority, false);
-
-	JNIEnv* env = JNU_GetEnv();
-
-	jobjectArray array =
-		(jobjectArray)env->CallObjectMethod(_back_ptr, MID_getSysArchives);
-	if (env->ExceptionCheck()) {
-		warning("Error finding system archive path");
-		env->ExceptionDescribe();
-		env->ExceptionClear();
-		return;
-	}
-
-	jsize size = env->GetArrayLength(array);
-	for (jsize i = 0; i < size; ++i) {
-		jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
-		const char* path = env->GetStringUTFChars(path_obj, NULL);
-		if (path != NULL) {
-			s.addDirectory(path, path, priority);
-			env->ReleaseStringUTFChars(path_obj, path);
-		}
-		env->DeleteLocalRef(path_obj);
-	}
-}
-
-
-static jint ScummVM_scummVMMain(JNIEnv* env, jobject self, jobjectArray args) {
-	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
-
-	const int MAX_NARGS = 32;
-	int res = -1;
-
-	int argc = env->GetArrayLength(args);
-	if (argc > MAX_NARGS) {
-		JNU_ThrowByName(env, "java/lang/IllegalArgumentException",
-				"too many arguments");
-		return 0;
-	}
-
-	char* argv[MAX_NARGS];
-	int nargs;	// note use in cleanup loop below
-	for (nargs = 0; nargs < argc; ++nargs) {
-		jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
-		if (arg == NULL) {
-			argv[nargs] = NULL;
-		} else {
-			const char* cstr = env->GetStringUTFChars(arg, NULL);
-			argv[nargs] = const_cast<char*>(cstr);
-			if (cstr == NULL)
-				goto cleanup;  // exception already thrown
-		}
-		env->DeleteLocalRef(arg);
-	}
-
-	g_system = cpp_obj;
-	assert(g_system);
-	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,
-				"Entering scummvm_main with %d args", argc);
-	res = scummvm_main(argc, argv);
-	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Exiting scummvm_main");
-	g_system->quit();
-
-cleanup:
-	nargs--;
-	for (int i = 0; i < nargs; ++i) {
-		if (argv[i] == NULL)
-			continue;
-		jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
-		if (arg == NULL)
-			// Exception already thrown
-			return res;
-		env->ReleaseStringUTFChars(arg, argv[i]);
-		env->DeleteLocalRef(arg);
-	}
-
-	return res;
-}
-
-#ifdef DYNAMIC_MODULES
-void AndroidPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
-	OSystem_Android* g_system_android = (OSystem_Android*)g_system;
-	g_system_android->addPluginDirectories(dirs);
-}
-#endif
-
-const static JNINativeMethod gMethods[] = {
-	{ "create", "(Landroid/content/res/AssetManager;)V",
-	  (void*)ScummVM_create },
-	{ "nativeDestroy", "()V", (void*)ScummVM_nativeDestroy },
-	{ "scummVMMain", "([Ljava/lang/String;)I",
-	  (void*)ScummVM_scummVMMain },
-	{ "pushEvent", "(Lorg/inodes/gus/scummvm/Event;)V",
-	  (void*)ScummVM_pushEvent },
-	{ "audioMixCallback", "([B)V",
-	  (void*)ScummVM_audioMixCallback },
-	{ "setConfMan", "(Ljava/lang/String;I)V",
-	  (void*)ScummVM_setConfManInt },
-	{ "setConfMan", "(Ljava/lang/String;Ljava/lang/String;)V",
-	  (void*)ScummVM_setConfManString },
-};
-
-JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM* jvm, void* reserved) {
-	cached_jvm = jvm;
-
-	JNIEnv* env;
-	if (jvm->GetEnv((void**)&env, JNI_VERSION_1_2))
-		return JNI_ERR;
-
-	jclass cls = env->FindClass("org/inodes/gus/scummvm/ScummVM");
-	if (cls == NULL)
-		return JNI_ERR;
-	if (env->RegisterNatives(cls, gMethods, ARRAYSIZE(gMethods)) < 0)
-		return JNI_ERR;
-
-	FID_ScummVM_nativeScummVM = env->GetFieldID(cls, "nativeScummVM", "J");
-	if (FID_ScummVM_nativeScummVM == NULL)
-		return JNI_ERR;
-
-	jclass event = env->FindClass("org/inodes/gus/scummvm/Event");
-	if (event == NULL)
-		return JNI_ERR;
-	FID_Event_type = env->GetFieldID(event, "type", "I");
-	if (FID_Event_type == NULL)
-		return JNI_ERR;
-	FID_Event_synthetic = env->GetFieldID(event, "synthetic", "Z");
-	if (FID_Event_synthetic == NULL)
-		return JNI_ERR;
-	FID_Event_kbd_keycode = env->GetFieldID(event, "kbd_keycode", "I");
-	if (FID_Event_kbd_keycode == NULL)
-		return JNI_ERR;
-	FID_Event_kbd_ascii = env->GetFieldID(event, "kbd_ascii", "I");
-	if (FID_Event_kbd_ascii == NULL)
-		return JNI_ERR;
-	FID_Event_kbd_flags = env->GetFieldID(event, "kbd_flags", "I");
-	if (FID_Event_kbd_flags == NULL)
-		return JNI_ERR;
-	FID_Event_mouse_x = env->GetFieldID(event, "mouse_x", "I");
-	if (FID_Event_mouse_x == NULL)
-		return JNI_ERR;
-	FID_Event_mouse_y = env->GetFieldID(event, "mouse_y", "I");
-	if (FID_Event_mouse_y == NULL)
-		return JNI_ERR;
-	FID_Event_mouse_relative = env->GetFieldID(event, "mouse_relative", "Z");
-	if (FID_Event_mouse_relative == NULL)
-		return JNI_ERR;
-
-	cls = env->FindClass("java/lang/Object");
-	if (cls == NULL)
-		return JNI_ERR;
-	MID_Object_wait = env->GetMethodID(cls, "wait", "()V");
-	if (MID_Object_wait == NULL)
-		return JNI_ERR;
-
-	return JNI_VERSION_1_2;
-}
-
-#endif

Copied: scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp (from rev 49497, scummvm/trunk/backends/platform/android/android.cpp)
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp	                        (rev 0)
+++ scummvm/branches/gsoc2010-opengl/backends/platform/android/android.cpp	2010-06-08 03:31:27 UTC (rev 49499)
@@ -0,0 +1,1413 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "backends/base-backend.h"
+#include "base/main.h"
+#include "graphics/surface.h"
+
+#include "backends/platform/android/video.h"
+
+#if defined(ANDROID_BACKEND)
+
+#define ANDROID_VERSION_GE(major,minor) \
+  (ANDROID_MAJOR_VERSION > (major) || \
+   (ANDROID_MAJOR_VERSION == (major) && ANDROID_MINOR_VERSION >= (minor)))
+
+#include <jni.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+#include <android/log.h>
+
+#include "common/archive.h"
+#include "common/util.h"
+#include "common/rect.h"
+#include "common/queue.h"
+#include "common/mutex.h"
+#include "common/events.h"
+#include "common/config-manager.h"
+
+#include "backends/fs/posix/posix-fs-factory.h"
+#include "backends/keymapper/keymapper.h"
+#include "backends/saves/default/default-saves.h"
+#include "backends/timer/default/default-timer.h"
+#include "backends/plugins/posix/posix-provider.h"
+#include "sound/mixer_intern.h"
+
+#include "backends/platform/android/asset-archive.h"
+
+#undef LOG_TAG
+#define LOG_TAG "ScummVM"
+
+#if 0
+#define ENTER(args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, args)
+#else
+#define ENTER(args...) /**/
+#endif
+
+// Fix JNIEXPORT declaration to actually do something useful
+#undef JNIEXPORT
+#define JNIEXPORT __attribute__ ((visibility("default")))
+
+static JavaVM *cached_jvm;
+static jfieldID FID_Event_type;
+static jfieldID FID_Event_synthetic;
+static jfieldID FID_Event_kbd_keycode;
+static jfieldID FID_Event_kbd_ascii;
+static jfieldID FID_Event_kbd_flags;
+static jfieldID FID_Event_mouse_x;
+static jfieldID FID_Event_mouse_y;
+static jfieldID FID_Event_mouse_relative;
+static jfieldID FID_ScummVM_nativeScummVM;
+static jmethodID MID_Object_wait;
+
+JNIEnv* JNU_GetEnv() {
+	JNIEnv* env;
+	bool version_unsupported =
+		cached_jvm->GetEnv((void**)&env, JNI_VERSION_1_2);
+	assert(! version_unsupported);
+	return env;
+}
+
+static void JNU_ThrowByName(JNIEnv* env, const char* name, const char* msg) {
+	jclass cls = env->FindClass(name);
+	// if cls is NULL, an exception has already been thrown
+	if (cls != NULL)
+		env->ThrowNew(cls, msg);
+	env->DeleteLocalRef(cls);
+}
+
+// floating point.	use sparingly.
+template <class T>
+static inline T scalef(T in, float numerator, float denominator) {
+	return static_cast<float>(in) * numerator / denominator;
+}
+
+static inline GLfixed xdiv(int numerator, int denominator) {
+	assert(numerator < (1<<16));
+	return (numerator << 16) / denominator;
+}
+
+#ifdef DYNAMIC_MODULES
+class AndroidPluginProvider : public POSIXPluginProvider {
+protected:
+	virtual void addCustomDirectories(Common::FSList &dirs) const;
+};
+#endif
+
+
+#if 0
+#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
+static const char* getGlErrStr(GLenum error) {
+	switch (error) {
+	case GL_NO_ERROR:		   return "GL_NO_ERROR";
+	case GL_INVALID_ENUM:	   return "GL_INVALID_ENUM";
+	case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
+	case GL_STACK_OVERFLOW:	   return "GL_STACK_OVERFLOW";
+	case GL_STACK_UNDERFLOW:   return "GL_STACK_UNDERFLOW";
+	case GL_OUT_OF_MEMORY:	   return "GL_OUT_OF_MEMORY";
+	}
+
+	static char buf[40];
+	snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
+	return buf;
+}
+static void checkGlError(const char* file, int line) {
+	GLenum error = glGetError();
+	if (error != GL_NO_ERROR)
+		warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
+}
+#else
+#define CHECK_GL_ERROR() do {} while (false)
+#endif
+
+class OSystem_Android : public BaseBackend {
+private:
+	jobject _back_ptr;	// back pointer to (java) peer instance
+	jmethodID MID_displayMessageOnOSD;
+	jmethodID MID_setWindowCaption;
+	jmethodID MID_initBackend;
+	jmethodID MID_audioSampleRate;
+	jmethodID MID_showVirtualKeyboard;
+	jmethodID MID_getSysArchives;
+	jmethodID MID_getPluginDirectories;
+	jmethodID MID_setupScummVMSurface;
+	jmethodID MID_destroyScummVMSurface;
+
+	int _screen_changeid;
+	EGLDisplay _egl_display;
+	EGLSurface _egl_surface;
+	EGLint _egl_surface_width;
+	EGLint _egl_surface_height;
+
+	bool _force_redraw;
+
+	// Game layer
+	GLESPaletteTexture* _game_texture;
+	int _shake_offset;
+	bool _full_screen_dirty;
+	Common::Array<Common::Rect> _dirty_rects;
+
+	// Overlay layer
+	GLES4444Texture* _overlay_texture;
+	bool _show_overlay;
+
+	// Mouse layer
+	GLESPaletteATexture* _mouse_texture;
+	Common::Point _mouse_hotspot;
+	int _mouse_targetscale;
+	bool _show_mouse;
+	bool _use_mouse_palette;
+
+	Common::Queue<Common::Event> _event_queue;
+	MutexRef _event_queue_lock;
+
+	bool _timer_thread_exit;
+	pthread_t _timer_thread;
+	static void* timerThreadFunc(void* arg);
+
+	bool _virtkeybd_on;
+
+	Common::SaveFileManager *_savefile;
+	Audio::MixerImpl *_mixer;
+	Common::TimerManager *_timer;
+	FilesystemFactory *_fsFactory;
+	Common::Archive *_asset_archive;
+	timeval _startTime;
+
+	void setupScummVMSurface();
+	void destroyScummVMSurface();
+	void setupKeymapper();
+	void _setCursorPalette(const byte *colors, uint start, uint num);
+
+public:
+	OSystem_Android(jobject am);
+	virtual ~OSystem_Android();
+	bool initJavaHooks(JNIEnv* env, jobject self);
+
+	static OSystem_Android* fromJavaObject(JNIEnv* env, jobject obj);
+	virtual void initBackend();
+	void addPluginDirectories(Common::FSList &dirs) const;
+
+	virtual bool hasFeature(Feature f);
+	virtual void setFeatureState(Feature f, bool enable);
+	virtual bool getFeatureState(Feature f);
+	virtual const GraphicsMode *getSupportedGraphicsModes() const;
+	virtual int getDefaultGraphicsMode() const;
+	bool setGraphicsMode(const char *name);
+	virtual bool setGraphicsMode(int mode);
+	virtual int getGraphicsMode() const;
+	virtual void initSize(uint width, uint height,
+				  const Graphics::PixelFormat *format);
+	virtual int getScreenChangeID() const { return _screen_changeid; }
+	virtual int16 getHeight();
+	virtual int16 getWidth();
+	virtual void setPalette(const byte *colors, uint start, uint num);
+	virtual void grabPalette(byte *colors, uint start, uint num);
+	virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
+	virtual void updateScreen();
+	virtual Graphics::Surface *lockScreen();
+	virtual void unlockScreen();
+	virtual void setShakePos(int shakeOffset);
+	virtual void fillScreen(uint32 col);
+	virtual void setFocusRectangle(const Common::Rect& rect);
+	virtual void clearFocusRectangle();
+
+	virtual void showOverlay();
+	virtual void hideOverlay();
+	virtual void clearOverlay();
+	virtual void grabOverlay(OverlayColor *buf, int pitch);
+	virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
+	virtual int16 getOverlayHeight();
+	virtual int16 getOverlayWidth();
+	virtual Graphics::PixelFormat getOverlayFormat() const {
+		// RGBA 4444
+		Graphics::PixelFormat format;
+		format.bytesPerPixel = 2;
+		format.rLoss = 8 - 4;
+		format.gLoss = 8 - 4;
+		format.bLoss = 8 - 4;
+		format.aLoss = 8 - 4;
+		format.rShift = 3*4;
+		format.gShift = 2*4;
+		format.bShift = 1*4;
+		format.aShift = 0*4;
+		return format;
+	}
+
+	virtual bool showMouse(bool visible);
+
+	virtual void warpMouse(int x, int y);
+	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
+	virtual void setCursorPalette(const byte *colors, uint start, uint num);
+	virtual void disableCursorPalette(bool disable);
+
+	virtual bool pollEvent(Common::Event &event);
+	void pushEvent(const Common::Event& event);
+	virtual uint32 getMillis();
+	virtual void delayMillis(uint msecs);
+
+	virtual MutexRef createMutex(void);
+	virtual void lockMutex(MutexRef mutex);
+	virtual void unlockMutex(MutexRef mutex);
+	virtual void deleteMutex(MutexRef mutex);
+
+	virtual void quit();
+
+	virtual void setWindowCaption(const char *caption);
+	virtual void displayMessageOnOSD(const char *msg);
+	virtual void showVirtualKeyboard(bool enable);
+
+	virtual Common::SaveFileManager *getSavefileManager();
+	virtual Audio::Mixer *getMixer();
+	virtual void getTimeAndDate(TimeDate &t) const;
+	virtual Common::TimerManager *getTimerManager();
+	virtual FilesystemFactory *getFilesystemFactory();
+	virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
+};
+
+OSystem_Android::OSystem_Android(jobject am)
+	: _back_ptr(0),
+	  _egl_display(EGL_NO_DISPLAY),
+	  _egl_surface(EGL_NO_SURFACE),
+	  _screen_changeid(0),
+	  _force_redraw(false),
+	  _game_texture(NULL),
+	  _overlay_texture(NULL),
+	  _mouse_texture(NULL),
+	  _use_mouse_palette(false),
+	  _show_mouse(false),
+	  _show_overlay(false),
+	  _savefile(0),
+	  _mixer(0),
+	  _timer(0),
+	  _fsFactory(new POSIXFilesystemFactory()),
+	  _asset_archive(new AndroidAssetArchive(am)),
+	  _shake_offset(0),
+	  _full_screen_dirty(false),
+	  _event_queue_lock(createMutex()) {
+}
+
+OSystem_Android::~OSystem_Android() {
+	ENTER("~OSystem_Android()");
+	delete _game_texture;
+	delete _overlay_texture;
+	delete _mouse_texture;
+	destroyScummVMSurface();
+	JNIEnv* env = JNU_GetEnv();
+	//env->DeleteWeakGlobalRef(_back_ptr);
+	env->DeleteGlobalRef(_back_ptr);
+	delete _savefile;
+	delete _mixer;
+	delete _timer;
+	delete _fsFactory;
+	delete _asset_archive;
+	deleteMutex(_event_queue_lock);
+}
+
+OSystem_Android* OSystem_Android::fromJavaObject(JNIEnv* env, jobject obj) {
+	jlong peer = env->GetLongField(obj, FID_ScummVM_nativeScummVM);
+	return (OSystem_Android*)peer;
+}
+
+bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
+	// weak global ref to allow class to be unloaded
+	// ... except dalvik doesn't implement NewWeakGlobalRef (yet)
+	//_back_ptr = env->NewWeakGlobalRef(self);
+	_back_ptr = env->NewGlobalRef(self);
+
+	jclass cls = env->GetObjectClass(_back_ptr);
+
+#define FIND_METHOD(name, signature) do {						\
+		MID_ ## name = env->GetMethodID(cls, #name, signature); \
+		if (MID_ ## name == NULL)								\
+			return false;										\
+	} while (0)
+
+	FIND_METHOD(setWindowCaption, "(Ljava/lang/String;)V");
+	FIND_METHOD(displayMessageOnOSD, "(Ljava/lang/String;)V");
+	FIND_METHOD(initBackend, "()V");
+	FIND_METHOD(audioSampleRate, "()I");
+	FIND_METHOD(showVirtualKeyboard, "(Z)V");
+	FIND_METHOD(getSysArchives, "()[Ljava/lang/String;");
+	FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
+	FIND_METHOD(setupScummVMSurface, "()V");
+	FIND_METHOD(destroyScummVMSurface, "()V");
+
+#undef FIND_METHOD
+
+	return true;
+}
+
+static void ScummVM_create(JNIEnv* env, jobject self, jobject am) {
+	OSystem_Android* cpp_obj = new OSystem_Android(am);
+	if (!cpp_obj->initJavaHooks(env, self))
+		// Exception already thrown by initJavaHooks
+		return;
+
+	env->SetLongField(self, FID_ScummVM_nativeScummVM, (jlong)cpp_obj);
+
+#ifdef DYNAMIC_MODULES
+	PluginManager::instance().addPluginProvider(new AndroidPluginProvider());
+#endif
+}
+
+static void ScummVM_nativeDestroy(JNIEnv* env, jobject self) {
+	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+	delete cpp_obj;
+}
+
+static void ScummVM_audioMixCallback(JNIEnv* env, jobject self,
+									 jbyteArray jbuf) {
+	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+	jsize len = env->GetArrayLength(jbuf);
+	jbyte* buf = env->GetByteArrayElements(jbuf, NULL);
+	if (buf == NULL) {
+		warning("Unable to get Java audio byte array. Skipping.");
+		return;
+	}
+	Audio::MixerImpl* mixer =
+		static_cast<Audio::MixerImpl*>(cpp_obj->getMixer());
+	assert(mixer);
+	mixer->mixCallback(reinterpret_cast<byte*>(buf), len);
+	env->ReleaseByteArrayElements(jbuf, buf, 0);
+}
+
+static void ScummVM_setConfManInt(JNIEnv* env, jclass cls,
+				  jstring key_obj, jint value) {
+	ENTER("setConfManInt(%p, %d)", key_obj, (int)value);
+	const char* key = env->GetStringUTFChars(key_obj, NULL);
+	if (key == NULL)
+		return;
+	ConfMan.setInt(key, value);
+	env->ReleaseStringUTFChars(key_obj, key);
+}
+
+static void ScummVM_setConfManString(JNIEnv* env, jclass cls, jstring key_obj,
+					 jstring value_obj) {
+	ENTER("setConfManStr(%p, %p)", key_obj, value_obj);
+	const char* key = env->GetStringUTFChars(key_obj, NULL);
+	if (key == NULL)
+		return;
+	const char* value = env->GetStringUTFChars(value_obj, NULL);
+	if (value == NULL) {
+		env->ReleaseStringUTFChars(key_obj, key);
+		return;
+	}
+	ConfMan.set(key, value);
+	env->ReleaseStringUTFChars(value_obj, value);
+	env->ReleaseStringUTFChars(key_obj, key);
+}
+
+void* OSystem_Android::timerThreadFunc(void* arg) {
+	OSystem_Android* system = (OSystem_Android*)arg;
+	DefaultTimerManager* timer = (DefaultTimerManager*)(system->_timer);
+
+	struct timespec tv;
+	tv.tv_sec = 0;
+	tv.tv_nsec = 100 * 1000 * 1000;	// 100ms
+
+	while (!system->_timer_thread_exit) {
+		timer->handler();
+		nanosleep(&tv, NULL);
+	}
+
+	return NULL;
+}
+
+void OSystem_Android::initBackend() {
+	ENTER("initBackend()");
+	JNIEnv* env = JNU_GetEnv();
+
+	ConfMan.setInt("autosave_period", 0);
+	ConfMan.setInt("FM_medium_quality", true);
+
+	// must happen before creating TimerManager to avoid race in
+	// creating EventManager
+	setupKeymapper();
+
+	// BUG: "transient" ConfMan settings get nuked by the options
+	// screen.	Passing the savepath in this way makes it stick
+	// (via ConfMan.registerDefault)
+	_savefile = new DefaultSaveFileManager(ConfMan.get("savepath"));
+	_timer = new DefaultTimerManager();
+
+	gettimeofday(&_startTime, NULL);
+
+	jint sample_rate = env->CallIntMethod(_back_ptr, MID_audioSampleRate);
+	if (env->ExceptionCheck()) {
+		warning("Error finding audio sample rate - assuming 11025HZ");
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+		sample_rate = 11025;
+	}
+	_mixer = new Audio::MixerImpl(this, sample_rate);
+	_mixer->setReady(true);
+
+	env->CallVoidMethod(_back_ptr, MID_initBackend);
+	if (env->ExceptionCheck()) {
+		error("Error in Java initBackend");
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+	}
+
+	_timer_thread_exit = false;
+	pthread_create(&_timer_thread, NULL, timerThreadFunc, this);
+
+	OSystem::initBackend();
+
+	setupScummVMSurface();
+}
+
+void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
+	ENTER("OSystem_Android::addPluginDirectories()");
+	JNIEnv* env = JNU_GetEnv();
+
+	jobjectArray array =
+		(jobjectArray)env->CallObjectMethod(_back_ptr, MID_getPluginDirectories);
+	if (env->ExceptionCheck()) {
+		warning("Error finding plugin directories");
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+		return;
+	}
+
+	jsize size = env->GetArrayLength(array);
+	for (jsize i = 0; i < size; ++i) {
+		jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
+		if (path_obj == NULL)
+			continue;
+		const char* path = env->GetStringUTFChars(path_obj, NULL);
+		if (path == NULL) {
+			warning("Error getting string characters from plugin directory");
+			env->ExceptionClear();
+			env->DeleteLocalRef(path_obj);
+			continue;
+		}
+		dirs.push_back(Common::FSNode(path));
+		env->ReleaseStringUTFChars(path_obj, path);
+		env->DeleteLocalRef(path_obj);
+	}
+}
+
+bool OSystem_Android::hasFeature(Feature f) {
+	return (f == kFeatureCursorHasPalette ||
+		f == kFeatureVirtualKeyboard ||
+		f == kFeatureOverlaySupportsAlpha);
+}
+
+void OSystem_Android::setFeatureState(Feature f, bool enable) {
+	ENTER("setFeatureState(%d, %d)", f, enable);
+	switch (f) {
+	case kFeatureVirtualKeyboard:
+		_virtkeybd_on = enable;
+		showVirtualKeyboard(enable);
+		break;
+	default:
+		break;
+	}
+}
+
+bool OSystem_Android::getFeatureState(Feature f) {
+	switch (f) {
+	case kFeatureVirtualKeyboard:
+		return _virtkeybd_on;
+	default:
+		return false;
+	}
+}
+
+const OSystem::GraphicsMode* OSystem_Android::getSupportedGraphicsModes() const {
+	static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+		{"default", "Default", 1},
+		{0, 0, 0},
+	};
+	return s_supportedGraphicsModes;
+}
+
+
+int OSystem_Android::getDefaultGraphicsMode() const {
+	return 1;
+}
+
+bool OSystem_Android::setGraphicsMode(const char *mode) {
+	ENTER("setGraphicsMode(%s)", mode);
+	return true;
+}
+
+bool OSystem_Android::setGraphicsMode(int mode) {
+	ENTER("setGraphicsMode(%d)", mode);
+	return true;
+}
+
+int OSystem_Android::getGraphicsMode() const {
+	return 1;
+}
+
+void OSystem_Android::setupScummVMSurface() {
+	JNIEnv* env = JNU_GetEnv();
+	env->CallVoidMethod(_back_ptr, MID_setupScummVMSurface);
+	if (env->ExceptionCheck())
+		return;
+
+	// EGL set up with a new surface.  Initialise OpenGLES context.
+
+	_egl_display = eglGetCurrentDisplay();
+	_egl_surface = eglGetCurrentSurface(EGL_DRAW);
+
+	static bool log_version = true;
+	if (log_version) {
+		__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
+							"Using EGL %s (%s); GL %s/%s (%s)",
+							eglQueryString(_egl_display, EGL_VERSION),
+							eglQueryString(_egl_display, EGL_VENDOR),
+							glGetString(GL_VERSION),
+							glGetString(GL_RENDERER),
+							glGetString(GL_VENDOR));
+		log_version = false;		// only log this once
+	}
+
+	GLESTexture::initGLExtensions();
+
+	if (!eglQuerySurface(_egl_display, _egl_surface,
+						 EGL_WIDTH, &_egl_surface_width) ||
+		!eglQuerySurface(_egl_display, _egl_surface,
+						 EGL_HEIGHT, &_egl_surface_height)) {
+		JNU_ThrowByName(env, "java/lang/RuntimeException",
+						"Error fetching EGL surface width/height");
+		return;
+	}
+	__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
+						"New surface is %dx%d",
+						_egl_surface_width, _egl_surface_height);
+
+	CHECK_GL_ERROR();
+
+	// Turn off anything that looks like 3D ;)
+	glDisable(GL_CULL_FACE);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_LIGHTING);
+	glDisable(GL_FOG);
+	glDisable(GL_DITHER);
+	glShadeModel(GL_FLAT);
+	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	glEnable(GL_TEXTURE_2D);
+
+	if (!_game_texture)
+		_game_texture = new GLESPaletteTexture();
+	else
+		_game_texture->reinitGL();
+
+	if (!_overlay_texture)
+		_overlay_texture = new GLES4444Texture();
+	else
+		_overlay_texture->reinitGL();
+
+	if (!_mouse_texture)
+		_mouse_texture = new GLESPaletteATexture();
+	else
+		_mouse_texture->reinitGL();
+
+	glViewport(0, 0, _egl_surface_width, _egl_surface_height);
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	CHECK_GL_ERROR();
+
+	_force_redraw = true;
+}
+
+void OSystem_Android::destroyScummVMSurface() {
+	_egl_surface = EGL_NO_SURFACE;
+	JNIEnv* env = JNU_GetEnv();
+	env->CallVoidMethod(_back_ptr, MID_destroyScummVMSurface);
+	// Can't use OpenGLES functions after this
+}
+
+void OSystem_Android::initSize(uint width, uint height,
+							   const Graphics::PixelFormat *format) {
+	ENTER("initSize(%d,%d,%p)", width, height, format);
+
+	_game_texture->allocBuffer(width, height);
+
+	// Cap at 320x200 or the ScummVM themes abort :/
+	GLuint overlay_width = MIN(_egl_surface_width, 320);
+	GLuint overlay_height = MIN(_egl_surface_height, 200);
+	_overlay_texture->allocBuffer(overlay_width, overlay_height);
+
+	// Don't know mouse size yet - it gets reallocated in
+	// setMouseCursor.	We need the palette allocated before
+	// setMouseCursor however, so just take a guess at the desired
+	// size (it's small).
+	_mouse_texture->allocBuffer(20, 20);
+}
+
+int16 OSystem_Android::getHeight() {
+	return _game_texture->height();
+}
+
+int16 OSystem_Android::getWidth() {
+	return _game_texture->width();
+}
+
+void OSystem_Android::setPalette(const byte* colors, uint start, uint num) {
+		ENTER("setPalette(%p, %u, %u)", colors, start, num);
+
+	if (!_use_mouse_palette)
+		_setCursorPalette(colors, start, num);
+
+	byte* palette = _game_texture->palette() + start*3;
+	do {
+		for (int i = 0; i < 3; ++i)
+			palette[i] = colors[i];
+		palette += 3;
+		colors += 4;
+	} while (--num);
+}
+
+void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
+	ENTER("grabPalette(%p, %u, %u)", colors, start, num);
+	const byte* palette = _game_texture->palette_const() + start*3;
+	do {
+		for (int i = 0; i < 3; ++i)
+			colors[i] = palette[i];
+		colors[3] = 0xff;  // alpha
+
+		palette += 3;
+		colors += 4;
+	} while (--num);
+}
+
+void OSystem_Android::copyRectToScreen(const byte *buf, int pitch,
+					   int x, int y, int w, int h) {
+	ENTER("copyRectToScreen(%p, %d, %d, %d, %d, %d)",
+		  buf, pitch, x, y, w, h);
+
+	_game_texture->updateBuffer(x, y, w, h, buf, pitch);
+}
+
+void OSystem_Android::updateScreen() {
+	//ENTER("updateScreen()");
+
+	if (!_force_redraw &&
+		!_game_texture->dirty() &&
+		!_overlay_texture->dirty() &&
+		!_mouse_texture->dirty())
+		return;
+
+	_force_redraw = false;
+
+	glPushMatrix();
+
+	if (_shake_offset != 0) {
+		// This is the only case where _game_texture doesn't
+		// cover the entire screen.
+		glClearColorx(0, 0, 0, 1 << 16);
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		// Move everything up by _shake_offset (game) pixels
+		glTranslatex(0, -_shake_offset << 16, 0);
+	}
+
+	_game_texture->drawTexture(0, 0,
+				   _egl_surface_width, _egl_surface_height);
+
+	CHECK_GL_ERROR();
+
+	if (_show_overlay) {
+		_overlay_texture->drawTexture(0, 0,
+						  _egl_surface_width,
+						  _egl_surface_height);
+		CHECK_GL_ERROR();
+	}
+
+	if (_show_mouse) {
+		glPushMatrix();
+
+		glTranslatex(-_mouse_hotspot.x << 16,
+				 -_mouse_hotspot.y << 16,
+				 0);
+
+		// Scale up ScummVM -> OpenGL (pixel) coordinates
+		int texwidth, texheight;
+		if (_show_overlay) {
+			texwidth = getOverlayWidth();
+			texheight = getOverlayHeight();
+		} else {
+			texwidth = getWidth();
+			texheight = getHeight();
+		}
+		glScalex(xdiv(_egl_surface_width, texwidth),
+			 xdiv(_egl_surface_height, texheight),
+			 1 << 16);
+
+		// Note the extra half texel to position the mouse in
+		// the middle of the x,y square:
+		const Common::Point& mouse = getEventManager()->getMousePos();
+		glTranslatex((mouse.x << 16) | 1 << 15,
+					 (mouse.y << 16) | 1 << 15, 0);
+
+		// Mouse targetscale just seems to make the cursor way
+		// too big :/
+		//glScalex(_mouse_targetscale << 16, _mouse_targetscale << 16,
+		//	 1 << 16);
+
+		_mouse_texture->drawTexture();
+
+		glPopMatrix();
+	}
+
+	glPopMatrix();
+
+	CHECK_GL_ERROR();
+
+	if (!eglSwapBuffers(_egl_display, _egl_surface)) {
+		EGLint error = eglGetError();
+		warning("eglSwapBuffers exited with error 0x%x", error);
+		// Some errors mean we need to reinit GL
+		if (error == EGL_CONTEXT_LOST) {
+			destroyScummVMSurface();
+			setupScummVMSurface();
+		}
+	}
+}
+
+Graphics::Surface *OSystem_Android::lockScreen() {
+	ENTER("lockScreen()");
+	Graphics::Surface* surface = _game_texture->surface();
+	assert(surface->pixels);
+	return surface;
+}
+
+void OSystem_Android::unlockScreen() {
+	ENTER("unlockScreen()");
+	assert(_game_texture->dirty());
+}
+
+void OSystem_Android::setShakePos(int shake_offset) {
+	ENTER("setShakePos(%d)", shake_offset);
+	if (_shake_offset != shake_offset) {
+		_shake_offset = shake_offset;
+		_force_redraw = true;
+	}
+}
+
+void OSystem_Android::fillScreen(uint32 col) {
+	ENTER("fillScreen(%u)", col);
+	assert(col < 256);
+	_game_texture->fillBuffer(col);
+}
+
+void OSystem_Android::setFocusRectangle(const Common::Rect& rect) {
+	ENTER("setFocusRectangle(%d,%d,%d,%d)",
+		  rect.left, rect.top, rect.right, rect.bottom);
+#if 0
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrthof(rect.left, rect.right, rect.top, rect.bottom, 0, 1);
+	glMatrixMode(GL_MODELVIEW);
+
+	_force_redraw = true;
+#endif
+}
+
+void OSystem_Android::clearFocusRectangle() {
+	ENTER("clearFocusRectangle()");
+#if 0
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
+	glMatrixMode(GL_MODELVIEW);
+
+	_force_redraw = true;
+#endif
+}
+
+void OSystem_Android::showOverlay() {
+	ENTER("showOverlay()");
+	_show_overlay = true;
+	_force_redraw = true;
+}
+
+void OSystem_Android::hideOverlay() {
+	ENTER("hideOverlay()");
+	_show_overlay = false;
+	_force_redraw = true;
+}
+
+void OSystem_Android::clearOverlay() {
+	ENTER("clearOverlay()");
+	_overlay_texture->fillBuffer(0);
+}
+
+void OSystem_Android::grabOverlay(OverlayColor *buf, int pitch) {
+	ENTER("grabOverlay(%p, %d)", buf, pitch);
+	// We support overlay alpha blending, so the pixel data here
+	// shouldn't actually be used.	Let's fill it with zeros, I'm sure
+	// it will be fine...
+	const Graphics::Surface* surface = _overlay_texture->surface_const();
+	assert(surface->bytesPerPixel == sizeof(buf[0]));
+	int h = surface->h;
+	do {
+		memset(buf, 0, surface->w * sizeof(buf[0]));
+		buf += pitch;  // This 'pitch' is pixels not bytes
+	} while (--h);
+}
+
+void OSystem_Android::copyRectToOverlay(const OverlayColor *buf, int pitch,
+					int x, int y, int w, int h) {
+	ENTER("copyRectToOverlay(%p, %d, %d, %d, %d, %d)",
+		 buf, pitch, x, y, w, h);
+	const Graphics::Surface* surface = _overlay_texture->surface_const();
+	assert(surface->bytesPerPixel == sizeof(buf[0]));
+
+	// This 'pitch' is pixels not bytes
+	_overlay_texture->updateBuffer(x, y, w, h, buf, pitch * sizeof(buf[0]));
+}
+
+int16 OSystem_Android::getOverlayHeight() {
+	return _overlay_texture->height();
+}
+
+int16 OSystem_Android::getOverlayWidth() {
+	return _overlay_texture->width();
+}
+
+bool OSystem_Android::showMouse(bool visible) {
+	ENTER("showMouse(%d)", visible);
+	_show_mouse = visible;
+	return true;
+}
+
+void OSystem_Android::warpMouse(int x, int y) {
+	ENTER("warpMouse(%d, %d)", x, y);
+	// We use only the eventmanager's idea of the current mouse
+	// position, so there is nothing extra to do here.
+}
+
+void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
+					 int hotspotX, int hotspotY,
+					 uint32 keycolor, int cursorTargetScale,
+					 const Graphics::PixelFormat *format) {
+	ENTER("setMouseCursor(%p, %u, %u, %d, %d, %d, %d, %p)",
+		  buf, w, h, hotspotX, hotspotY, (int)keycolor, cursorTargetScale,
+		  format);
+
+	assert(keycolor < 256);
+
+	_mouse_texture->allocBuffer(w, h);
+
+	// Update palette alpha based on keycolor
+	byte* palette = _mouse_texture->palette();
+	int i = 256;
+	do {
+		palette[3] = 0xff;
+		palette += 4;
+	} while (--i);
+	palette = _mouse_texture->palette();
+	palette[keycolor*4 + 3] = 0x00;
+	_mouse_texture->updateBuffer(0, 0, w, h, buf, w);
+
+	_mouse_hotspot = Common::Point(hotspotX, hotspotY);
+	_mouse_targetscale = cursorTargetScale;
+}
+
+void OSystem_Android::_setCursorPalette(const byte *colors,
+					uint start, uint num) {
+	byte* palette = _mouse_texture->palette() + start*4;
+	do {
+		for (int i = 0; i < 3; ++i)
+			palette[i] = colors[i];
+		// Leave alpha untouched to preserve keycolor
+
+		palette += 4;
+		colors += 4;
+	} while (--num);
+}
+
+void OSystem_Android::setCursorPalette(const byte *colors,
+					   uint start, uint num) {
+	ENTER("setCursorPalette(%p, %u, %u)", colors, start, num);
+	_setCursorPalette(colors, start, num);
+	_use_mouse_palette = true;
+}
+
+void OSystem_Android::disableCursorPalette(bool disable) {
+	ENTER("disableCursorPalette(%d)", disable);
+	_use_mouse_palette = !disable;
+}
+
+void OSystem_Android::setupKeymapper() {
+#ifdef ENABLE_KEYMAPPER
+	using namespace Common;
+
+	Keymapper *mapper = getEventManager()->getKeymapper();
+
+	HardwareKeySet *keySet = new HardwareKeySet();
+	keySet->addHardwareKey(
+		new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
+				kTriggerLeftKeyType,
+				kVirtualKeyboardActionType));
+	mapper->registerHardwareKeySet(keySet);
+
+	Keymap *globalMap = new Keymap("global");
+	Action *act;
+
+	act = new Action(globalMap, "VIRT", "Display keyboard",
+			 kVirtualKeyboardActionType);
+	act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+
+	mapper->addGlobalKeymap(globalMap);
+
+	mapper->pushKeymap("global");
+#endif
+}
+
+bool OSystem_Android::pollEvent(Common::Event &event) {
+	//ENTER("pollEvent()");
+	lockMutex(_event_queue_lock);
+	if (_event_queue.empty()) {
+		unlockMutex(_event_queue_lock);
+		return false;
+	}
+	event = _event_queue.pop();
+	unlockMutex(_event_queue_lock);
+
+	switch (event.type) {
+	case Common::EVENT_MOUSEMOVE:
+		// TODO: only dirty/redraw move bounds
+		_force_redraw = true;
+		// fallthrough
+	case Common::EVENT_LBUTTONDOWN:
+	case Common::EVENT_LBUTTONUP:
+	case Common::EVENT_RBUTTONDOWN:
+	case Common::EVENT_RBUTTONUP:
+	case Common::EVENT_WHEELUP:
+	case Common::EVENT_WHEELDOWN:
+	case Common::EVENT_MBUTTONDOWN:
+	case Common::EVENT_MBUTTONUP: {
+		if (event.kbd.flags == 1) { // relative mouse hack
+			// Relative (trackball) mouse hack.
+			const Common::Point& mouse_pos =
+				getEventManager()->getMousePos();
+			event.mouse.x += mouse_pos.x;
+			event.mouse.y += mouse_pos.y;
+			event.mouse.x = CLIP(event.mouse.x, (int16)0, _show_overlay ?
+								 getOverlayWidth() : getWidth());
+			event.mouse.y = CLIP(event.mouse.y, (int16)0, _show_overlay ?
+								 getOverlayHeight() : getHeight());
+		} else {
+			// Touchscreen events need to be converted
+			// from device to game coords first.
+			const GLESTexture* tex = _show_overlay
+				? static_cast<GLESTexture*>(_overlay_texture)
+				: static_cast<GLESTexture*>(_game_texture);
+			event.mouse.x = scalef(event.mouse.x, tex->width(),
+								   _egl_surface_width);
+			event.mouse.y = scalef(event.mouse.y, tex->height(),
+								   _egl_surface_height);
+			event.mouse.x -= _shake_offset;
+		}
+		break;
+	}
+	case Common::EVENT_SCREEN_CHANGED:
+		debug("EVENT_SCREEN_CHANGED");
+		_screen_changeid++;
+		destroyScummVMSurface();
+		setupScummVMSurface();
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+void OSystem_Android::pushEvent(const Common::Event& event) {
+	lockMutex(_event_queue_lock);
+
+	// Try to combine multiple queued mouse move events
+	if (event.type == Common::EVENT_MOUSEMOVE &&
+		!_event_queue.empty() &&
+		_event_queue.back().type == Common::EVENT_MOUSEMOVE) {
+	  Common::Event tail = _event_queue.back();
+	  if (event.kbd.flags) {
+		// relative movement hack
+		tail.mouse.x += event.mouse.x;
+		tail.mouse.y += event.mouse.y;
+	  } else {
+		// absolute position
+		tail.kbd.flags = 0;	 // clear relative flag
+		tail.mouse.x = event.mouse.x;
+		tail.mouse.y = event.mouse.y;
+	  }
+	}
+	else
+	  _event_queue.push(event);
+
+	unlockMutex(_event_queue_lock);
+}
+
+static void ScummVM_pushEvent(JNIEnv* env, jobject self, jobject java_event) {
+	OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+
+	Common::Event event;
+	event.type = (Common::EventType)env->GetIntField(java_event,
+							 FID_Event_type);
+	event.synthetic =
+		env->GetBooleanField(java_event, FID_Event_synthetic);
+
+	switch (event.type) {
+	case Common::EVENT_KEYDOWN:
+	case Common::EVENT_KEYUP:
+		event.kbd.keycode = (Common::KeyCode)env->GetIntField(
+			java_event, FID_Event_kbd_keycode);
+		event.kbd.ascii = static_cast<int>(env->GetIntField(
+			java_event, FID_Event_kbd_ascii));
+		event.kbd.flags = static_cast<int>(env->GetIntField(
+			java_event, FID_Event_kbd_flags));
+		break;
+	case Common::EVENT_MOUSEMOVE:
+	case Common::EVENT_LBUTTONDOWN:
+	case Common::EVENT_LBUTTONUP:
+	case Common::EVENT_RBUTTONDOWN:
+	case Common::EVENT_RBUTTONUP:
+	case Common::EVENT_WHEELUP:
+	case Common::EVENT_WHEELDOWN:
+	case Common::EVENT_MBUTTONDOWN:
+	case Common::EVENT_MBUTTONUP:
+		event.mouse.x =
+			env->GetIntField(java_event, FID_Event_mouse_x);
+		event.mouse.y =
+			env->GetIntField(java_event, FID_Event_mouse_y);
+		// This is a terrible hack.	 We stash "relativeness"
+		// in the kbd.flags field until pollEvent() can work
+		// it out.
+		event.kbd.flags = env->GetBooleanField(
+			java_event, FID_Event_mouse_relative) ? 1 : 0;
+		break;
+	default:
+		break;
+	}
+
+	cpp_obj->pushEvent(event);
+}
+
+uint32 OSystem_Android::getMillis() {
+	timeval curTime;
+	gettimeofday(&curTime, NULL);
+	return (uint32)(((curTime.tv_sec - _startTime.tv_sec) * 1000) + \
+			((curTime.tv_usec - _startTime.tv_usec) / 1000));
+}
+
+void OSystem_Android::delayMillis(uint msecs) {
+	usleep(msecs * 1000);
+}
+
+OSystem::MutexRef OSystem_Android::createMutex() {
+	pthread_mutexattr_t attr;
+	pthread_mutexattr_init(&attr);
+	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+	pthread_mutex_t *mutex = new pthread_mutex_t;
+	if (pthread_mutex_init(mutex, &attr) != 0) {
+		warning("pthread_mutex_init() failed!");
+		delete mutex;
+		return NULL;
+	}
+	return (MutexRef)mutex;
+}
+
+void OSystem_Android::lockMutex(MutexRef mutex) {
+	if (pthread_mutex_lock((pthread_mutex_t*)mutex) != 0)
+		warning("pthread_mutex_lock() failed!");
+}
+
+void OSystem_Android::unlockMutex(MutexRef mutex) {
+	if (pthread_mutex_unlock((pthread_mutex_t*)mutex) != 0)
+		warning("pthread_mutex_unlock() failed!");
+}
+
+void OSystem_Android::deleteMutex(MutexRef mutex) {
+	pthread_mutex_t* m = (pthread_mutex_t*)mutex;
+	if (pthread_mutex_destroy(m) != 0)
+		warning("pthread_mutex_destroy() failed!");
+	else
+		delete m;
+}
+
+void OSystem_Android::quit() {
+	ENTER("quit()");
+
+	_timer_thread_exit = true;
+	pthread_join(_timer_thread, NULL);
+}
+
+void OSystem_Android::setWindowCaption(const char *caption) {
+	ENTER("setWindowCaption(%s)", caption);
+	JNIEnv* env = JNU_GetEnv();
+	jstring java_caption = env->NewStringUTF(caption);
+	env->CallVoidMethod(_back_ptr, MID_setWindowCaption, java_caption);
+	if (env->ExceptionCheck()) {
+		warning("Failed to set window caption");
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+	}
+	env->DeleteLocalRef(java_caption);
+}
+
+void OSystem_Android::displayMessageOnOSD(const char *msg) {
+	ENTER("displayMessageOnOSD(%s)", msg);
+	JNIEnv* env = JNU_GetEnv();
+	jstring java_msg = env->NewStringUTF(msg);
+	env->CallVoidMethod(_back_ptr, MID_displayMessageOnOSD, java_msg);

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list