commit d0ad39648b5d8b9cba29e19cd0aa3374c6b54cc4
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Mar 31 17:24:38 2023 +0200

    Decouple (to a large degree) the OpenGL Library from Android.

diff --git a/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java b/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
index 67255737..9c4ba4d5 100644
--- a/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
+++ b/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
@@ -12,6 +12,7 @@ package org.distorted.bandaged;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
@@ -19,6 +20,10 @@ import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
 import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLES31;
 import android.opengl.GLSurfaceView;
 import android.widget.Toast;
@@ -46,7 +51,7 @@ import org.json.JSONException;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    public static final float BRIGHTNESS = 0.333f;
    private static final int RESET_DURATION = 1000;
@@ -55,6 +60,7 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
    private static final float INIT_RATIO = 0.5f;
 
    private final BandagedCreatorView mView;
+   private final Resources mResources;
    private final DistortedScreen mScreen;
    private final Static3D mScale;
    private final Static4D mQuatT, mQuatA;
@@ -78,11 +84,12 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
 
    BandagedCreatorRenderer(BandagedCreatorView v)
      {
+     mView = v;
+     mResources = v.getResources();
+
      mQuatT = new Static4D(0,0,0,1);
      mQuatA = new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
 
-     mView = v;
-
      mResetQuats       = false;
      mSetQuatT         = false;
      mResettingObject  = false;
@@ -303,7 +310,7 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
 
       FragmentEffectBrightness.enable();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
 
       if( mCubits==null )
@@ -320,13 +327,6 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
       mHeight= 0;
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   public void distortedException(Exception ex)
-     {
-     android.util.Log.e("CREATOR", "unexpected exception: "+ex.getMessage() );
-     }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    public DistortedScreen getScreen()
@@ -670,4 +670,39 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
     {
     if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked();
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void distortedException(Exception ex)
+    {
+    android.util.Log.e("BandagedCreator", "unexpected exception: "+ex.getMessage() );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int openGlVersion()
+    {
+    Context context = mView.getContext();
+    final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+    int glESversion = configurationInfo.reqGlEsVersion;
+    int major = glESversion >> 16;
+    int minor = glESversion & 0xff;
+
+    return 100*major + 10*minor;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public InputStream localFile(int fileID)
+    {
+    return mResources.openRawResource(fileID);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void logMessage(String message)
+    {
+    android.util.Log.e("BandagedCreator", message );
+    }
 }
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java b/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
index d24ead07..7b72c2ea 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
@@ -9,6 +9,10 @@
 
 package org.distorted.bandaged;
 
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.effect.EffectType;
@@ -20,14 +24,17 @@ import org.distorted.library.mesh.MeshBase;
 import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.scrambling.ScrambleStateBandagedCuboid;
 
+import java.io.InputStream;
+
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    private final BandagedPlayView mView;
+   private final Resources mResources;
    private final DistortedScreen mScreen;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -37,6 +44,7 @@ public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLi
      final float BRIGHTNESS = 0.333f;
 
      mView = v;
+     mResources = v.getResources();
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
      }
@@ -60,6 +68,13 @@ public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLi
       mView.setScreenSize(width,height);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   DistortedScreen getScreen()
+     {
+     return mScreen;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    @Override
@@ -74,7 +89,7 @@ public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLi
       VertexEffectQuaternion.enable();
       BaseEffect.Type.enableEffects();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
       }
 
@@ -87,8 +102,29 @@ public class BandagedPlayRenderer implements GLSurfaceView.Renderer, DistortedLi
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   DistortedScreen getScreen()
-     {
-     return mScreen;
-     }
+   public int openGlVersion()
+      {
+      Context context = mView.getContext();
+      final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+      final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+      int glESversion = configurationInfo.reqGlEsVersion;
+      int major = glESversion >> 16;
+      int minor = glESversion & 0xff;
+
+      return 100*major + 10*minor;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public InputStream localFile(int fileID)
+      {
+      return mResources.openRawResource(fileID);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public void logMessage(String message)
+      {
+      android.util.Log.e("BandagedPlay", message );
+      }
 }
diff --git a/src/main/java/org/distorted/config/ConfigRenderer.java b/src/main/java/org/distorted/config/ConfigRenderer.java
index 7ac08fc2..1b56f5bd 100644
--- a/src/main/java/org/distorted/config/ConfigRenderer.java
+++ b/src/main/java/org/distorted/config/ConfigRenderer.java
@@ -9,6 +9,10 @@
 
 package org.distorted.config;
 
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.effect.EffectType;
@@ -19,14 +23,17 @@ import org.distorted.library.main.DistortedScreen;
 import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.main.ObjectControl;
 
+import java.io.InputStream;
+
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    private final ConfigSurfaceView mView;
+   private final Resources mResources;
    private final DistortedScreen mScreen;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -36,6 +43,7 @@ public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.
      final float BRIGHTNESS = 0.333f;
 
      mView = v;
+     mResources = v.getResources();
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
      }
@@ -59,6 +67,13 @@ public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.
       mView.setScreenSize(width,height);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   DistortedScreen getScreen()
+     {
+     return mScreen;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    @Override
@@ -69,7 +84,7 @@ public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.
       VertexEffectQuaternion.enable();
       BaseEffect.Type.enableEffects();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
       }
 
@@ -77,13 +92,34 @@ public class ConfigRenderer implements GLSurfaceView.Renderer, DistortedLibrary.
 
    public void distortedException(Exception ex)
      {
-     android.util.Log.e("CONFIG", "unexpected exception: "+ex.getMessage() );
+     android.util.Log.e("Config", "unexpected exception: "+ex.getMessage() );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   DistortedScreen getScreen()
-     {
-     return mScreen;
-     }
+   public int openGlVersion()
+      {
+      Context context = mView.getContext();
+      final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+      final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+      int glESversion = configurationInfo.reqGlEsVersion;
+      int major = glESversion >> 16;
+      int minor = glESversion & 0xff;
+
+      return 100*major + 10*minor;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public InputStream localFile(int fileID)
+      {
+      return mResources.openRawResource(fileID);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public void logMessage(String message)
+      {
+      android.util.Log.e("Config", message );
+      }
 }
diff --git a/src/main/java/org/distorted/main/RubikRenderer.java b/src/main/java/org/distorted/main/RubikRenderer.java
index 06f4413b..35c6af99 100644
--- a/src/main/java/org/distorted/main/RubikRenderer.java
+++ b/src/main/java/org/distorted/main/RubikRenderer.java
@@ -10,6 +10,10 @@
 package org.distorted.main;
 
 import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
@@ -30,13 +34,16 @@ import javax.microedition.khronos.opengles.GL10;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
+import java.io.InputStream;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    public static final float BRIGHTNESS = 0.30f;
 
    private final RubikSurfaceView mView;
+   private final Resources mResources;
    private final DistortedScreen mScreen;
    private final ObjectControl mControl;
    private final Fps mFPS;
@@ -85,8 +92,10 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
 
    RubikRenderer(RubikSurfaceView v)
      {
-     mErrorShown = false;
      mView = v;
+     mResources = v.getResources();
+
+     mErrorShown = false;
      mControl = v.getObjectControl();
      mFPS = new Fps();
      mScreen = new DistortedScreen();
@@ -94,6 +103,20 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
      mScreen.enableDepthStencil(InternalOutputSurface.DEPTH_NO_STENCIL);
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   float getFPS()
+     {
+     return mFPS.getFPS();
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   DistortedScreen getScreen()
+     {
+     return mScreen;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // various things are done here delayed, 'after the next render' as not to be done mid-render and
 // cause artifacts.
@@ -129,7 +152,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
       BaseEffect.Type.enableEffects();
       OverlayGeneric.enableEffects();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
 
       if( !mDebugSent )
@@ -184,15 +207,29 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   float getFPS()
+   public int openGlVersion()
      {
-     return mFPS.getFPS();
+     Context context = mView.getContext();
+     final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+     final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+     int glESversion = configurationInfo.reqGlEsVersion;
+     int major = glESversion >> 16;
+     int minor = glESversion & 0xff;
+
+     return 100*major + 10*minor;
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   DistortedScreen getScreen()
+   public InputStream localFile(int fileID)
      {
-     return mScreen;
+     return mResources.openRawResource(fileID);
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public void logMessage(String message)
+     {
+     android.util.Log.e("Rubik", message );
      }
 }
diff --git a/src/main/java/org/distorted/purchase/PurchaseRenderer.java b/src/main/java/org/distorted/purchase/PurchaseRenderer.java
index a049e04c..c0d7ab81 100644
--- a/src/main/java/org/distorted/purchase/PurchaseRenderer.java
+++ b/src/main/java/org/distorted/purchase/PurchaseRenderer.java
@@ -9,6 +9,10 @@
 
 package org.distorted.purchase;
 
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.effect.EffectType;
@@ -21,17 +25,20 @@ import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.overlays.OverlayGeneric;
 
+import java.io.InputStream;
+
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    private static final int NUM_SCRAMBLES = 5;
    private static final int DURATION = NUM_SCRAMBLES*2*1000;
 
    private final PurchaseSurfaceView mView;
+   private final Resources mResources;
    private final DistortedScreen mScreen;
 
    private boolean mFirstRender;
@@ -42,8 +49,10 @@ public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrar
      {
      final float BRIGHTNESS = 0.333f;
 
-     mFirstRender = true;
      mView = v;
+     mResources = v.getResources();
+
+     mFirstRender = true;
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
      }
@@ -73,6 +82,13 @@ public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrar
       mView.setScreenSize(width,height);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   DistortedScreen getScreen()
+     {
+     return mScreen;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    @Override
@@ -86,7 +102,7 @@ public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrar
       BaseEffect.Type.enableEffects();
       OverlayGeneric.enableEffects();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
       }
 
@@ -94,13 +110,34 @@ public class PurchaseRenderer implements GLSurfaceView.Renderer, DistortedLibrar
 
    public void distortedException(Exception ex)
      {
-     android.util.Log.e("PURCHASE", "unexpected exception: "+ex.getMessage() );
+     android.util.Log.e("Purchase", "unexpected exception: "+ex.getMessage() );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   DistortedScreen getScreen()
-     {
-     return mScreen;
-     }
+   public int openGlVersion()
+      {
+      Context context = mView.getContext();
+      final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+      final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+      int glESversion = configurationInfo.reqGlEsVersion;
+      int major = glESversion >> 16;
+      int minor = glESversion & 0xff;
+
+      return 100*major + 10*minor;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public InputStream localFile(int fileID)
+      {
+      return mResources.openRawResource(fileID);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public void logMessage(String message)
+      {
+      android.util.Log.e("Purchase", message );
+      }
 }
diff --git a/src/main/java/org/distorted/tutorials/TutorialRenderer.java b/src/main/java/org/distorted/tutorials/TutorialRenderer.java
index d9966f1c..b68a4154 100644
--- a/src/main/java/org/distorted/tutorials/TutorialRenderer.java
+++ b/src/main/java/org/distorted/tutorials/TutorialRenderer.java
@@ -12,6 +12,10 @@ package org.distorted.tutorials;
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.effect.EffectType;
@@ -24,12 +28,15 @@ import org.distorted.library.mesh.MeshBase;
 import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.main.ObjectControl;
 
+import java.io.InputStream;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TutorialRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
+public class TutorialRenderer implements GLSurfaceView.Renderer, DistortedLibrary.LibraryUser
 {
    private final TutorialSurfaceView mView;
    private final DistortedScreen mScreen;
+   private final Resources mResources;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -38,10 +45,18 @@ public class TutorialRenderer implements GLSurfaceView.Renderer, DistortedLibrar
      final float BRIGHTNESS = 0.30f;
 
      mView = v;
+     mResources = v.getResources();
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   DistortedScreen getScreen()
+     {
+     return mScreen;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    @Override
@@ -73,7 +88,7 @@ public class TutorialRenderer implements GLSurfaceView.Renderer, DistortedLibrar
       VertexEffectQuaternion.enable();
       BaseEffect.Type.enableEffects();
 
-      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
+      DistortedLibrary.onSurfaceCreated(this,1);
       DistortedLibrary.setCull(true);
       }
 
@@ -81,13 +96,34 @@ public class TutorialRenderer implements GLSurfaceView.Renderer, DistortedLibrar
 
    public void distortedException(Exception ex)
      {
-     android.util.Log.e("TUTORIAL", "unexpected exception: "+ex.getMessage() );
+     android.util.Log.e("Tutorial", "unexpected exception: "+ex.getMessage() );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   DistortedScreen getScreen()
+   public int openGlVersion()
      {
-     return mScreen;
+     Context context = mView.getContext();
+     final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+     final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+     int glESversion = configurationInfo.reqGlEsVersion;
+     int major = glESversion >> 16;
+     int minor = glESversion & 0xff;
+
+     return 100*major + 10*minor;
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public InputStream localFile(int fileID)
+     {
+     return mResources.openRawResource(fileID);
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public void logMessage(String message)
+     {
+     android.util.Log.e("Tutorial", message );
      }
 }
