Dialog to calibrate gyroscope

This commit is contained in:
pelya
2013-02-02 21:50:14 +02:00
parent bba4301405
commit 0ea01bface
8 changed files with 208 additions and 14 deletions

View File

@@ -435,7 +435,7 @@ if [ -n "$var" ] ; then
fi
fi
FirstStartMenuOptionsDefault='(AppUsesMouse \&\& \! ForceRelativeMouseMode ? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true)'
FirstStartMenuOptionsDefault='(AppUsesMouse \&\& \! ForceRelativeMouseMode ? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration()'
if [ -z "$AUTO" ]; then
echo
echo "Menu items to show at startup - this is Java code snippet, leave empty for default"
@@ -929,8 +929,8 @@ mkdir -p project/src
cd project/java
for F in *.java; do
echo Patching $F
echo '// DO NOT EDIT THIS FILE - it is automatically generated, edit file under project/java dir' > ../src/$F
cat $F | sed "s/package .*;/package $AppFullName;/" >> ../src/$F
echo '// DO NOT EDIT THIS FILE - it is automatically generated, ALL YOUR CHANGES WILL BE OVERWRITTEN, edit the file under project/java dir' > ../src/$F
cat $F | sed "s/package .*;/package $AppFullName;/" >> ../src/$F # | sed 's@$@ // THIS FILE IS AUTO-GENERATED@' >>
done
cd ../..

View File

@@ -42,7 +42,7 @@ class AccelerometerReader implements SensorEventListener
private SensorManager _manager = null;
public boolean openedBySDL = false;
private final GyroscopeListener gyro = new GyroscopeListener();
public static final GyroscopeListener gyro = new GyroscopeListener();
public AccelerometerReader(Activity context)
{
@@ -61,12 +61,13 @@ class AccelerometerReader implements SensorEventListener
public synchronized void start()
{
if( (Globals.UseAccelerometerAsArrowKeys || Globals.AppUsesAccelerometer) && _manager != null )
if( (Globals.UseAccelerometerAsArrowKeys || Globals.AppUsesAccelerometer) &&
_manager != null && _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null )
{
System.out.println("libSDL: starting accelerometer");
_manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
if( Globals.AppUsesGyroscope && _manager != null )
if( Globals.AppUsesGyroscope && _manager != null && _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null )
{
System.out.println("libSDL: starting gyroscope");
_manager.registerListener(gyro, _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
@@ -84,8 +85,9 @@ class AccelerometerReader implements SensorEventListener
{
}
class GyroscopeListener implements SensorEventListener
static class GyroscopeListener implements SensorEventListener
{
public float x1, x2, xc, y1, y2, yc, z1, z2, zc;
public GyroscopeListener()
{
}
@@ -93,11 +95,33 @@ class AccelerometerReader implements SensorEventListener
{
// TODO: vertical orientation
//if( Globals.HorizontalOrientation )
nativeGyroscope(event.values[0], event.values[1], event.values[2]);
if( event.values[0] < x1 || event.values[0] > x2 ||
event.values[1] < y1 || event.values[1] > y2 ||
event.values[2] < z1 || event.values[2] > z2 )
nativeGyroscope(event.values[0] - xc, event.values[1] - yc, event.values[2] - zc);
}
public synchronized void onAccuracyChanged(Sensor s, int a)
public void onAccuracyChanged(Sensor s, int a)
{
}
public boolean available(Activity context)
{
SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
return ( manager != null && manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null );
}
public void registerListener(Activity context, SensorEventListener l)
{
SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if ( manager == null && manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) == null )
return;
manager.registerListener(l, manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
public void unregisterListener(Activity context,SensorEventListener l)
{
SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if ( manager == null )
return;
manager.unregisterListener(l);
}
}
private static native void nativeAccelerometer(float accX, float accY, float accZ);

View File

@@ -64,7 +64,7 @@ class Globals
public static int StartupMenuButtonTimeout = 3000;
public static int AppMinimumRAM = 0;
public static Settings.Menu HiddenMenuOptions [] = {};
public static Settings.Menu FirstStartMenuOptions [] = { (AppUsesMouse && ! ForceRelativeMouseMode ? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true) };
public static Settings.Menu FirstStartMenuOptions [] = { (AppUsesMouse && ! ForceRelativeMouseMode ? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration() };
public static String AdmobPublisherId = "";
public static String AdmobTestDeviceId = "";
public static String AdmobBannerSize = "";
@@ -113,4 +113,6 @@ class Globals
public static boolean VideoLinearFilter = true;
public static boolean MultiThreadedVideo = false;
public static boolean BrokenLibCMessageShown = false;
// Gyroscope calibration
public static float gyro_x1, gyro_x2, gyro_xc, gyro_y1, gyro_y2, gyro_yc, gyro_z1, gyro_z2, gyro_zc;
}

View File

@@ -67,6 +67,9 @@ import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
// TODO: too much code here, split into multiple files, possibly auto-generated menus?
class Settings
@@ -154,6 +157,15 @@ class Settings
out.writeBoolean(Globals.BrokenLibCMessageShown);
out.writeInt(Globals.TouchscreenKeyboardDrawSize);
out.writeInt(p.getApplicationVersion());
out.writeFloat(Globals.gyro_x1);
out.writeFloat(Globals.gyro_x2);
out.writeFloat(Globals.gyro_xc);
out.writeFloat(Globals.gyro_y1);
out.writeFloat(Globals.gyro_y2);
out.writeFloat(Globals.gyro_yc);
out.writeFloat(Globals.gyro_z1);
out.writeFloat(Globals.gyro_z2);
out.writeFloat(Globals.gyro_zc);
out.close();
settingsLoaded = true;
@@ -300,6 +312,15 @@ class Settings
Globals.BrokenLibCMessageShown = settingsFile.readBoolean();
Globals.TouchscreenKeyboardDrawSize = settingsFile.readInt();
int cfgVersion = settingsFile.readInt();
Globals.gyro_x1 = settingsFile.readFloat();
Globals.gyro_x2 = settingsFile.readFloat();
Globals.gyro_xc = settingsFile.readFloat();
Globals.gyro_y1 = settingsFile.readFloat();
Globals.gyro_y2 = settingsFile.readFloat();
Globals.gyro_yc = settingsFile.readFloat();
Globals.gyro_z1 = settingsFile.readFloat();
Globals.gyro_z2 = settingsFile.readFloat();
Globals.gyro_zc = settingsFile.readFloat();
settingsLoaded = true;
@@ -531,6 +552,7 @@ class Settings
new MouseConfigMainMenu(),
new ArrowKeysConfig(),
new AccelerometerConfig(),
new GyroscopeCalibration(),
new AudioConfig(),
new RemapHwKeysConfig(),
new ScreenGesturesConfig(),
@@ -2486,6 +2508,149 @@ class Settings
}
}
static class GyroscopeCalibration extends Menu implements SensorEventListener
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.calibrate_gyroscope);
}
boolean enabled()
{
return Globals.AppUsesGyroscope;
}
void run (final MainActivity p)
{
if( !Globals.AppUsesGyroscope || !AccelerometerReader.gyro.available(p) )
{
goBack(p);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.calibrate_gyroscope));
builder.setMessage(p.getResources().getString(R.string.calibrate_gyroscope_text));
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
startCalibration(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
ImageView img;
Bitmap bmp;
int numEvents;
MainActivity p;
void startCalibration(final MainActivity _p)
{
p = _p;
img = new ImageView(p);
img.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
img.setScaleType(ImageView.ScaleType.MATRIX);
bmp = BitmapFactory.decodeResource( p.getResources(), R.drawable.calibrate );
img.setImageBitmap(bmp);
Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
RectF dst = new RectF( p.getVideoLayout().getWidth()/2 - 50, p.getVideoLayout().getHeight()/2 - 50,
p.getVideoLayout().getWidth()/2 + 50, p.getVideoLayout().getHeight()/2 + 50);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
img.setImageMatrix(m);
p.getVideoLayout().addView(img);
numEvents = 0;
AccelerometerReader.gyro.x1 = 0;
AccelerometerReader.gyro.x2 = 0;
AccelerometerReader.gyro.xc = 0;
AccelerometerReader.gyro.y1 = 0;
AccelerometerReader.gyro.y2 = 0;
AccelerometerReader.gyro.yc = 0;
AccelerometerReader.gyro.z1 = 0;
AccelerometerReader.gyro.z2 = 0;
AccelerometerReader.gyro.zc = 0;
AccelerometerReader.gyro.registerListener(p, this);
(new Thread(new Runnable()
{
public void run()
{
for(int count = 1; count < 10; count++)
{
p.setText("" + count + "0% ...");
try {
Thread.sleep(500);
} catch( Exception e ) {}
}
finishCalibration(p);
}
}
)).start();
}
public void onSensorChanged(SensorEvent event)
{
gyroscopeEvent(event.values[0], event.values[1], event.values[2]);
}
public void onAccuracyChanged(Sensor s, int a)
{
}
void gyroscopeEvent(float x, float y, float z)
{
numEvents++;
AccelerometerReader.gyro.xc += x;
AccelerometerReader.gyro.yc += y;
AccelerometerReader.gyro.zc += z;
AccelerometerReader.gyro.x1 = Math.min(AccelerometerReader.gyro.x1, x);
AccelerometerReader.gyro.x2 = Math.max(AccelerometerReader.gyro.x2, x);
AccelerometerReader.gyro.y1 = Math.min(AccelerometerReader.gyro.y1, y);
AccelerometerReader.gyro.y2 = Math.max(AccelerometerReader.gyro.y2, y);
AccelerometerReader.gyro.z1 = Math.min(AccelerometerReader.gyro.z1, z);
AccelerometerReader.gyro.z2 = Math.max(AccelerometerReader.gyro.z2, z);
final Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
RectF dst = new RectF( x * 5000 + p.getVideoLayout().getWidth()/2 - 50, y * 5000 + p.getVideoLayout().getHeight()/2 - 50,
x * 5000 + p.getVideoLayout().getWidth()/2 + 50, y * 5000 + p.getVideoLayout().getHeight()/2 + 50);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
p.runOnUiThread(new Runnable()
{
public void run()
{
img.setImageMatrix(m);
}
});
}
void finishCalibration(final MainActivity p)
{
AccelerometerReader.gyro.unregisterListener(p, this);
try {
Thread.sleep(200); // Just in case we have pending events
} catch( Exception e ) {}
if( numEvents > 0 )
{
AccelerometerReader.gyro.xc /= (float)numEvents;
AccelerometerReader.gyro.yc /= (float)numEvents;
AccelerometerReader.gyro.zc /= (float)numEvents;
}
p.runOnUiThread(new Runnable()
{
public void run()
{
p.getVideoLayout().removeView(img);
goBack(p);
}
});
}
}
// ===============================================================================================
public static boolean deleteRecursively(File dir)

View File

@@ -165,4 +165,7 @@
<string name="not_enough_ram_size">This app needs %1$d Mb RAM, your device has %2$d Mb</string>
<string name="ignore">Ignore</string>
<string name="calibrate_gyroscope">Calibrate gyroscope</string>
<string name="calibrate_gyroscope_text">Put your phone on a flat surface</string>
</resources>

View File

@@ -41,7 +41,7 @@ MultiABI=y
AppMinimumRAM=300
AppVersionCode=08819
AppVersionName="0.8.8.19"
ResetSdlConfigForThisVersion=y
ResetSdlConfigForThisVersion=n
DeleteFilesOnUpgrade="libsdl-DownloadFinished-10.flag"
CompiledLibraries="sdl_mixer sdl_image freetype curl vorbis ogg"
CustomBuildScript=y

View File

@@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-15
target=android-17

View File

@@ -10,10 +10,10 @@ Also this port is developed very slowly, although the same is true for an offici
Installation
============
This project should be compiled with Android 3.1 SDK (API level 15) and NDK r8, r7c, r6 or r5c,
This project should be compiled with Android 4.2 SDK (API level 17) and NDK r8, r7c, r6 or r5c,
google for them and install them as described in their docs.
You'll need to install Java Ant too.
The application will run on Android OS 1.6 and above, don't mind the 3.1 dependency.
The application will run on Android OS 1.6 and above, but will use features from Android 4.2 if available.
Also it's compatible with NDK r4b and all versions of CrystaX NDK starting from r4b.
CrystaX NDK adds support for wide chars, and required if you want to use Boost libraries.
http://www.crystax.net/android/ndk.php