[SDL] Experimental adaptive algorithm for measuring gyroscope min/max values, removed the gyro calibration dialog
This commit is contained in:
@@ -36,6 +36,7 @@ import android.hardware.SensorEvent;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
import android.os.Build;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
class AccelerometerReader implements SensorEventListener
|
||||
@@ -105,33 +106,162 @@ class AccelerometerReader implements SensorEventListener
|
||||
|
||||
static class GyroscopeListener implements SensorEventListener
|
||||
{
|
||||
public float x1 = 0.0f, x2 = 0.0f, xc = 0.0f, y1 = 0.0f, y2 = 0.0f, yc = 0.0f, z1 = 0.0f, z2 = 0.0f, zc = 0.0f;
|
||||
public boolean invertedOrientation = false;
|
||||
|
||||
final float noiseMin[] = new float[] { -1.0f, -1.0f, -1.0f }; // Large initial values, they will only decrease
|
||||
final float noiseMax[] = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
float noiseData[][] = new float[200][3];
|
||||
int noiseDataIdx = noiseData.length * 3 / 4; // Speed up first measurement, to converge to sane values faster
|
||||
int noiseMovementDetected = 0;
|
||||
float noiseMeasuredRange[] = null;
|
||||
|
||||
static int noiseCounter = 0;
|
||||
|
||||
public GyroscopeListener()
|
||||
{
|
||||
}
|
||||
public void onSensorChanged(SensorEvent event)
|
||||
|
||||
void collectNoiseData(final float[] data)
|
||||
{
|
||||
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 )
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( Globals.HorizontalOrientation )
|
||||
if( data[i] < noiseMin[i] || data[i] > noiseMax[i] )
|
||||
{
|
||||
if( invertedOrientation )
|
||||
nativeGyroscope(-(event.values[0] - xc), -(event.values[1] - yc), event.values[2] - zc);
|
||||
else
|
||||
nativeGyroscope(event.values[0] - xc, event.values[1] - yc, event.values[2] - zc);
|
||||
// Movement detected, this can converge our min/max too early, so we're discarding last few values
|
||||
if( noiseMovementDetected < 0 )
|
||||
{
|
||||
int discard = 10;
|
||||
if( -noiseMovementDetected < discard )
|
||||
discard = -noiseMovementDetected;
|
||||
noiseDataIdx -= discard;
|
||||
if( noiseDataIdx < 0 )
|
||||
noiseDataIdx = 0;
|
||||
}
|
||||
noiseMovementDetected = 10;
|
||||
return;
|
||||
}
|
||||
else
|
||||
noiseData[noiseDataIdx][i] = data[i];
|
||||
}
|
||||
noiseMovementDetected--;
|
||||
if( noiseMovementDetected >= 0 )
|
||||
return; // Also discard several values after the movement stopped
|
||||
noiseDataIdx++;
|
||||
|
||||
if( noiseDataIdx < noiseData.length )
|
||||
return;
|
||||
|
||||
noiseCounter++;
|
||||
Log.i( "SDL", "GYRO_NOISE: Measuring in progress... " + noiseCounter ); // DEBUG
|
||||
if( noiseCounter > 15 )
|
||||
{
|
||||
Log.i( "SDL", "GYRO_NOISE: Measuring done! Max iteration reached " + noiseCounter ); // DEBUG
|
||||
noiseData = null;
|
||||
noiseMeasuredRange = null;
|
||||
}
|
||||
|
||||
noiseDataIdx = 0;
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
float min = 1.0f;
|
||||
float max = -1.0f;
|
||||
for( int ii = 0; ii < noiseData.length; ii++ )
|
||||
{
|
||||
if( invertedOrientation )
|
||||
nativeGyroscope(-(event.values[1] - yc), event.values[0] - xc, event.values[2] - zc);
|
||||
else
|
||||
nativeGyroscope(event.values[1] - yc, -(event.values[0] - xc), event.values[2] - zc);
|
||||
if( min > noiseData[ii][i] )
|
||||
min = noiseData[ii][i];
|
||||
if( max < noiseData[ii][i] )
|
||||
max = noiseData[ii][i];
|
||||
}
|
||||
// Increase the range a bit, for conservative noise filtering
|
||||
float middle = (min + max) / 2.0f;
|
||||
min += (min - middle) * 0.2f;
|
||||
max += (max - middle) * 0.2f;
|
||||
// Check if range between min/max is less then the current range, as a safety measure,
|
||||
// and min/max range is not jumping outside of previously measured range
|
||||
if( max - min < noiseMax[i] - noiseMin[i] && min >= noiseMin[i] && max <= noiseMax[i] )
|
||||
{
|
||||
noiseMax[i] = (noiseMax[i] + max * 4.0f) / 5.0f;
|
||||
noiseMin[i] = (noiseMin[i] + min * 4.0f) / 5.0f;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
Log.i( "SDL", "GYRO_NOISE: MIN MAX: " + Arrays.toString(noiseMin) + " " + Arrays.toString(noiseMax) ); // DEBUG
|
||||
|
||||
if( !changed )
|
||||
return;
|
||||
|
||||
// Determine when to stop measuring - check that the previous min/max range is close to the current one
|
||||
|
||||
float range[] = new float[3];
|
||||
for( int i = 0; i < 3; i++ )
|
||||
range[i] = noiseMax[i] - noiseMin[i];
|
||||
|
||||
Log.i( "SDL", "GYRO_NOISE: RANGE: " + Arrays.toString(range) + " " + Arrays.toString(noiseMeasuredRange) ); // DEBUG
|
||||
|
||||
if( noiseMeasuredRange == null )
|
||||
{
|
||||
noiseMeasuredRange = range;
|
||||
return;
|
||||
}
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( noiseMeasuredRange[i] / range[i] > 1.2f )
|
||||
{
|
||||
noiseMeasuredRange = range;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We converged to the final min/max, stop measuring
|
||||
noiseData = null;
|
||||
noiseMeasuredRange = null;
|
||||
Log.i( "SDL", "GYRO_NOISE: Measuring done! Range converged on iteration " + noiseCounter ); // DEBUG
|
||||
}
|
||||
|
||||
public void onSensorChanged(final SensorEvent event)
|
||||
{
|
||||
boolean filtered = true;
|
||||
final float[] data = event.values;
|
||||
|
||||
if( noiseData != null )
|
||||
collectNoiseData(data);
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( data[i] < noiseMin[i] )
|
||||
{
|
||||
filtered = false;
|
||||
data[i] -= noiseMin[i];
|
||||
}
|
||||
else if( data[i] > noiseMax[i] )
|
||||
{
|
||||
filtered = false;
|
||||
data[i] -= noiseMax[i];
|
||||
}
|
||||
}
|
||||
|
||||
if( filtered )
|
||||
return;
|
||||
|
||||
if( Globals.HorizontalOrientation )
|
||||
{
|
||||
if( invertedOrientation )
|
||||
nativeGyroscope(-data[0], -data[1], data[2]);
|
||||
else
|
||||
nativeGyroscope(data[0], data[1], data[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( invertedOrientation )
|
||||
nativeGyroscope(-data[1], data[0], data[2]);
|
||||
else
|
||||
nativeGyroscope(data[1], -data[0], data[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAccuracyChanged(Sensor s, int a)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -163,15 +163,16 @@ class Settings
|
||||
out.writeBoolean(false); // Unused
|
||||
out.writeInt(Globals.TouchscreenKeyboardDrawSize);
|
||||
out.writeInt(p.getApplicationVersion());
|
||||
out.writeFloat(AccelerometerReader.gyro.x1);
|
||||
out.writeFloat(AccelerometerReader.gyro.x2);
|
||||
out.writeFloat(AccelerometerReader.gyro.xc);
|
||||
out.writeFloat(AccelerometerReader.gyro.y1);
|
||||
out.writeFloat(AccelerometerReader.gyro.y2);
|
||||
out.writeFloat(AccelerometerReader.gyro.yc);
|
||||
out.writeFloat(AccelerometerReader.gyro.z1);
|
||||
out.writeFloat(AccelerometerReader.gyro.z2);
|
||||
out.writeFloat(AccelerometerReader.gyro.zc);
|
||||
// Gyroscope calibration data, now unused
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
out.writeFloat(0.0f);
|
||||
|
||||
out.writeBoolean(Globals.OuyaEmulation);
|
||||
out.writeBoolean(Globals.HoverJitterFilter);
|
||||
@@ -356,15 +357,16 @@ class Settings
|
||||
settingsFile.readBoolean(); // Unused
|
||||
Globals.TouchscreenKeyboardDrawSize = settingsFile.readInt();
|
||||
int cfgVersion = settingsFile.readInt();
|
||||
AccelerometerReader.gyro.x1 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.x2 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.xc = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.y1 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.y2 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.yc = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.z1 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.z2 = settingsFile.readFloat();
|
||||
AccelerometerReader.gyro.zc = settingsFile.readFloat();
|
||||
// Gyroscope calibration data, now unused
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
settingsFile.readFloat();
|
||||
|
||||
Globals.OuyaEmulation = settingsFile.readBoolean();
|
||||
Globals.HoverJitterFilter = settingsFile.readBoolean();
|
||||
|
||||
@@ -243,7 +243,6 @@ class SettingsMenu
|
||||
new SettingsMenuMisc.OptionalDownloadConfig(false),
|
||||
new SettingsMenuKeyboard.KeyboardConfigMainMenu(),
|
||||
new SettingsMenuMouse.MouseConfigMainMenu(),
|
||||
new SettingsMenuMisc.GyroscopeCalibration(),
|
||||
new SettingsMenuMisc.AudioConfig(),
|
||||
new SettingsMenuKeyboard.RemapHwKeysConfig(),
|
||||
new SettingsMenuKeyboard.ScreenGesturesConfig(),
|
||||
|
||||
@@ -589,157 +589,19 @@ class SettingsMenuMisc extends SettingsMenu
|
||||
}
|
||||
}
|
||||
|
||||
static class GyroscopeCalibration extends Menu implements SensorEventListener
|
||||
static class GyroscopeCalibration extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.calibrate_gyroscope);
|
||||
return "";
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.AppUsesGyroscope || Globals.MoveMouseWithGyroscope;
|
||||
return false;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
if( !(Globals.AppUsesGyroscope || Globals.MoveMouseWithGyroscope) || !AccelerometerReader.gyro.available(p) )
|
||||
{
|
||||
if( Globals.AppUsesGyroscope || Globals.MoveMouseWithGyroscope )
|
||||
{
|
||||
Toast toast = Toast.makeText(p, p.getResources().getString(R.string.calibrate_gyroscope_not_supported), Toast.LENGTH_LONG);
|
||||
toast.show();
|
||||
}
|
||||
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 = -10;
|
||||
AccelerometerReader.gyro.x1 = 100;
|
||||
AccelerometerReader.gyro.x2 = -100;
|
||||
AccelerometerReader.gyro.xc = 0;
|
||||
AccelerometerReader.gyro.y1 = 100;
|
||||
AccelerometerReader.gyro.y2 = -100;
|
||||
AccelerometerReader.gyro.yc = 0;
|
||||
AccelerometerReader.gyro.z1 = 100;
|
||||
AccelerometerReader.gyro.z2 = -100;
|
||||
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 * 10 + "% ...");
|
||||
try {
|
||||
Thread.sleep(300);
|
||||
} 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++;
|
||||
if (numEvents <= 0)
|
||||
return; // Skip few initial measurements, they may be incorrect
|
||||
AccelerometerReader.gyro.xc += x;
|
||||
AccelerometerReader.gyro.yc += y;
|
||||
AccelerometerReader.gyro.zc += z;
|
||||
AccelerometerReader.gyro.x1 = Math.min(AccelerometerReader.gyro.x1, x * 1.02f); // Small safety bound coefficient
|
||||
AccelerometerReader.gyro.x2 = Math.max(AccelerometerReader.gyro.x2, x * 1.02f);
|
||||
AccelerometerReader.gyro.y1 = Math.min(AccelerometerReader.gyro.y1, y * 1.02f);
|
||||
AccelerometerReader.gyro.y2 = Math.max(AccelerometerReader.gyro.y2, y * 1.02f);
|
||||
AccelerometerReader.gyro.z1 = Math.min(AccelerometerReader.gyro.z1, z * 1.02f);
|
||||
AccelerometerReader.gyro.z2 = Math.max(AccelerometerReader.gyro.z2, z * 1.02f);
|
||||
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 > 10 )
|
||||
{
|
||||
AccelerometerReader.gyro.xc /= (float)numEvents;
|
||||
AccelerometerReader.gyro.yc /= (float)numEvents;
|
||||
AccelerometerReader.gyro.zc /= (float)numEvents;
|
||||
Log.i("SDL", "libSDL: gyroscope calibration: " +
|
||||
AccelerometerReader.gyro.x1 + " < " + AccelerometerReader.gyro.xc + " > " + AccelerometerReader.gyro.x2 + " : " +
|
||||
AccelerometerReader.gyro.y1 + " < " + AccelerometerReader.gyro.yc + " > " + AccelerometerReader.gyro.y2 + " : " +
|
||||
AccelerometerReader.gyro.z1 + " < " + AccelerometerReader.gyro.zc + " > " + AccelerometerReader.gyro.z2);
|
||||
}
|
||||
p.runOnUiThread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
p.getVideoLayout().removeView(img);
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
279
project/jni/application/test-gyro/AndroidAppSettings.cfg
Normal file
279
project/jni/application/test-gyro/AndroidAppSettings.cfg
Normal file
@@ -0,0 +1,279 @@
|
||||
# The application settings for Android libSDL port
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="! Gyro test"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=gyro.test
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=101
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.01"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file
|
||||
AppDataDownloadUrl="!!Game data is 1 Mb|ballfield3.zip"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines (that's four backslashes)^de:Text in Deutsch^ru:Text in Russian^button:Button that will open some URL:http://url-to-open/
|
||||
ReadmeText='^Readme text'
|
||||
|
||||
# libSDL version to use (1.2/1.3/2.0)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Create Android service, so the app is less likely to be killed while in background
|
||||
CreateService=
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdate=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() after mouse click (ScummVM and all Amiga emulators do that) -
|
||||
# force screen update by moving mouse cursor a little after each click (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdateMouseClick=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y
|
||||
# 0 - standard Android keyboard
|
||||
# 1 - Simple QWERTY keyboard, no function keys, no arrow keys
|
||||
# 2 - Commodore 64 keyboard
|
||||
# 3 - Amiga keyboard
|
||||
TextInputKeyboard=1
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects.
|
||||
# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n)
|
||||
CompatibilityHacksProperUsageOfSDL_UpdateRects=n
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=y
|
||||
|
||||
# Right mouse button can do long-press/drag&drop action, necessary for some games (y) or (n)
|
||||
# If you disable it, swiping with two fingers will send mouse wheel events
|
||||
RightMouseButtonLongPress=n
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n)
|
||||
ScreenFollowsMouse=
|
||||
|
||||
# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)
|
||||
GenerateSubframeTouchEvents=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n)
|
||||
AppNeedsArrowKeys=n
|
||||
|
||||
# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n)
|
||||
# Joystick always follows finger, so moving mouse requires touching the screen with other finger
|
||||
FloatingScreenJoystick=n
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=n
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
# This will disable AppNeedsArrowKeys option
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses third on-screen joystick, as SDL joystick 0 axes 20-21 (y)/(n)
|
||||
AppUsesThirdJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=y
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=y
|
||||
|
||||
# Application uses orientation sensor (y) or (n), reported as joystick 1 axes 8-10
|
||||
AppUsesOrientationSensor=
|
||||
|
||||
# Use gyroscope to move mouse cursor (y) or (n), it eats battery, and can be disabled in settings, do not use with AppUsesGyroscope setting
|
||||
MoveMouseWithGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application needs to access SD card. If your data files are bigger than 5 Mb, enable it. (y) / (n)
|
||||
AccessSdCard=y
|
||||
|
||||
# Application needs Internet access. If you disable it, you'll have to bundle all your data files inside .apk (y) / (n)
|
||||
AccessInternet=
|
||||
|
||||
# Immersive mode - Android will hide on-screen Home/Back keys. Looks bad if you invoke Android keyboard. (y) / (n)
|
||||
ImmersiveMode=y
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="SPACE RETURN NO_REMAP NO_REMAP SPACE ESCAPE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="0 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
# On-screen keys theme
|
||||
# 0 = Ultimate Droid by Sean Stieber (green, with cross joystick)
|
||||
# 1 = Simple Theme by Beholder (white, with cross joystick)
|
||||
# 2 = Sun by Sirea (yellow, with round joystick)
|
||||
# 3 = Keen by Gerstrong (multicolor, with round joystick)
|
||||
# 4 = Retro by Santiago Radeff (red/white, with cross joystick)
|
||||
TouchscreenKeysTheme=4
|
||||
|
||||
# Redefine gamepad keys to SDL keysyms, button order is:
|
||||
# A B X Y L1 R1 L2 R2 LThumb RThumb
|
||||
RedefinedKeysGamepad="0 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=0
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
|
||||
HiddenMenuOptions=''
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
|
||||
FirstStartMenuOptions='SettingsMenu.DummyMenu'
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=0
|
||||
|
||||
# GCC version, 4.6 (default) or 4.8, CLANG is not supported yet
|
||||
NDK_TOOLCHAIN_VERSION=
|
||||
|
||||
# Specify architectures to compile, 'all' or 'y' to compile for all architectures.
|
||||
# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips
|
||||
MultiABI='armeabi-v7a'
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-O2 -finline-functions'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags='-fuse-ld=bfd'
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height)
|
||||
AdmobBannerSize=
|
||||
|
||||
# Google Play Game Services application ID, required for cloud saves to work
|
||||
GooglePlayGameServicesId=
|
||||
|
||||
BIN
project/jni/application/test-gyro/AndroidData/ballfield3.zip
Normal file
BIN
project/jni/application/test-gyro/AndroidData/ballfield3.zip
Normal file
Binary file not shown.
BIN
project/jni/application/test-gyro/icon.png
Normal file
BIN
project/jni/application/test-gyro/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
434
project/jni/application/test-gyro/test-gyro.cpp
Normal file
434
project/jni/application/test-gyro/test-gyro.cpp
Normal file
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* "Ballfield"
|
||||
*
|
||||
* (C) David Olofson <david@olofson.net>, 2002, 2003
|
||||
*
|
||||
* This software is released under the terms of the GPL.
|
||||
*
|
||||
* Contact author for permission if you want to use this
|
||||
* software, or work derived from it, under other terms.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <android/log.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_image.h>
|
||||
#include <SDL/SDL_screenkeyboard.h>
|
||||
|
||||
#define fprintf(X, ...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
|
||||
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
|
||||
|
||||
/*----------------------------------------------------------
|
||||
Definitions...
|
||||
----------------------------------------------------------*/
|
||||
|
||||
#define SCREEN_W 1280
|
||||
#define SCREEN_H 800
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
General tool functions
|
||||
----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Bump areas of low and high alpha to 0% or 100%
|
||||
* respectively, just in case the graphics contains
|
||||
* "alpha noise".
|
||||
*/
|
||||
SDL_Surface *clean_alpha(SDL_Surface *s)
|
||||
{
|
||||
SDL_Surface *work;
|
||||
SDL_Rect r;
|
||||
Uint32 *pixels;
|
||||
int pp;
|
||||
int x, y;
|
||||
|
||||
work = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h,
|
||||
32, 0xff000000, 0x00ff0000, 0x0000ff00,
|
||||
0x000000ff);
|
||||
if(!work)
|
||||
return NULL;
|
||||
|
||||
r.x = r.y = 0;
|
||||
r.w = s->w;
|
||||
r.h = s->h;
|
||||
if(SDL_BlitSurface(s, &r, work, NULL) < 0)
|
||||
{
|
||||
SDL_FreeSurface(work);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_LockSurface(work);
|
||||
pixels = (Uint32 *)work->pixels;
|
||||
pp = work->pitch / sizeof(Uint32);
|
||||
for(y = 0; y < work->h; ++y)
|
||||
for(x = 0; x < work->w; ++x)
|
||||
{
|
||||
Uint32 pix = pixels[y*pp + x];
|
||||
switch((pix & 0xff) >> 4)
|
||||
{
|
||||
case 0:
|
||||
pix = 0x00000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 15:
|
||||
pix |= 0xff;
|
||||
break;
|
||||
}
|
||||
pixels[y*pp + x] = pix;
|
||||
}
|
||||
SDL_UnlockSurface(work);
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load and convert an antialiazed, zoomed set of sprites.
|
||||
*/
|
||||
SDL_Surface *load_zoomed(char *name, int alpha)
|
||||
{
|
||||
SDL_Surface *sprites;
|
||||
SDL_Surface *temp = IMG_Load(name);
|
||||
if(!temp)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
sprites = temp;
|
||||
SDL_SetAlpha(sprites, 0, 255);
|
||||
temp = clean_alpha(sprites);
|
||||
SDL_FreeSurface(sprites);
|
||||
*/
|
||||
if(!temp)
|
||||
{
|
||||
fprintf(stderr, "Could not clean alpha!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(alpha)
|
||||
{
|
||||
SDL_SetAlpha(temp, 0, SDL_ALPHA_OPAQUE);
|
||||
sprites = SDL_DisplayFormatAlpha(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetColorKey(temp, SDL_SRCCOLORKEY,
|
||||
SDL_MapRGB(temp->format, 0, 0, 0));
|
||||
sprites = SDL_DisplayFormat(temp);
|
||||
}
|
||||
SDL_FreeSurface(temp);
|
||||
|
||||
return sprites;
|
||||
}
|
||||
|
||||
|
||||
void print_num(SDL_Surface *dst, SDL_Surface *font, int x, int y, float value)
|
||||
{
|
||||
char buf[16];
|
||||
int val = (int)(value * 10.0);
|
||||
int pos, p = 0;
|
||||
SDL_Rect from;
|
||||
|
||||
/* Sign */
|
||||
if(val < 0)
|
||||
{
|
||||
buf[p++] = 10;
|
||||
val = -val;
|
||||
}
|
||||
|
||||
/* Integer part */
|
||||
pos = 10000000;
|
||||
while(pos > 1)
|
||||
{
|
||||
int num = val / pos;
|
||||
val -= num * pos;
|
||||
pos /= 10;
|
||||
if(p || num)
|
||||
buf[p++] = num;
|
||||
}
|
||||
|
||||
/* Decimals */
|
||||
if(val / pos)
|
||||
{
|
||||
buf[p++] = 11;
|
||||
while(pos > 0)
|
||||
{
|
||||
int num = val / pos;
|
||||
val -= num * pos;
|
||||
pos /= 10;
|
||||
buf[p++] = num;
|
||||
}
|
||||
}
|
||||
|
||||
/* Render! */
|
||||
from.y = 0;
|
||||
from.w = 7;
|
||||
from.h = 10;
|
||||
for(pos = 0; pos < p; ++pos)
|
||||
{
|
||||
SDL_Rect to;
|
||||
to.x = x + pos * 7;
|
||||
to.y = y;
|
||||
from.x = buf[pos] * 7;
|
||||
SDL_BlitSurface(font, &from, dst, &to);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw tiled background image with offset.
|
||||
*/
|
||||
void tiled_back(SDL_Surface *back, SDL_Surface *screen, int xo, int yo)
|
||||
{
|
||||
SDL_Rect r;
|
||||
xo %= back->w/8;
|
||||
yo %= back->h/8;
|
||||
r.x = xo - back->w/2 + screen->w/2;
|
||||
r.y = yo - back->h/2 + screen->h/2;
|
||||
r.w = back->w;
|
||||
r.h = back->h;
|
||||
SDL_BlitSurface(back, NULL, screen, &r);
|
||||
}
|
||||
|
||||
void print_num_hex(SDL_Surface *dst, SDL_Surface *font, int x, int y, unsigned val)
|
||||
{
|
||||
char buf[8];
|
||||
int pos, p = 0;
|
||||
SDL_Rect from;
|
||||
|
||||
//val = htonl(val); // Big-endian
|
||||
|
||||
/* Render! */
|
||||
from.y = 0;
|
||||
from.w = 7;
|
||||
from.h = 10;
|
||||
for(pos = 0; pos < 8; ++pos)
|
||||
{
|
||||
SDL_Rect to;
|
||||
to.x = 8 * 7 - (x + pos * 7); // Little-endian number wrapped backwards
|
||||
to.y = y;
|
||||
from.x = ( ( val >> (pos * 4) ) & 0xf ) * 7;
|
||||
SDL_BlitSurface(font, &from, dst, &to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
main()
|
||||
----------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SDL_Surface *screen;
|
||||
SDL_Surface *temp_image;
|
||||
SDL_Surface *back, *logo, *font, *font_hex;
|
||||
SDL_Event event;
|
||||
int bpp = 16,
|
||||
flags = SDL_HWSURFACE,
|
||||
alpha = 1;
|
||||
int x_offs = 0, y_offs = 0;
|
||||
long tick,
|
||||
last_tick,
|
||||
last_avg_tick;
|
||||
double t = 0;
|
||||
float dt;
|
||||
int i;
|
||||
float fps = 0.0;
|
||||
int fps_count = 0;
|
||||
int fps_start = 0;
|
||||
float x_speed, y_speed, z_speed;
|
||||
enum { MAX_POINTERS = 16 };
|
||||
// some random colors
|
||||
int colors[MAX_POINTERS] = { 0xaaaaaa, 0xffffff, 0x888888, 0xcccccc, 0x666666, 0x999999, 0xdddddd, 0xeeeeee, 0xaaaaaa, 0xffffff, 0x888888, 0xcccccc, 0x666666, 0x999999, 0xdddddd, 0xeeeeee };
|
||||
struct TouchPointer_t { int x; int y; int pressure; int pressed; } touchPointers[MAX_POINTERS];
|
||||
int accel[5], screenjoy[4], gamepads[4][8];
|
||||
SDL_Surface *mouse[4];
|
||||
int screenKeyboardShown = 0;
|
||||
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
||||
SDL_EnableUNICODE(1);
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
SDL_Joystick * joysticks[6];
|
||||
for( i = 0; i < 6; i++ )
|
||||
joysticks[i] = SDL_JoystickOpen(i);
|
||||
|
||||
atexit(SDL_Quit);
|
||||
|
||||
screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, bpp, flags);
|
||||
if(!screen)
|
||||
{
|
||||
fprintf(stderr, "Failed to open screen!\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption("Ballfield", "Ballfield");
|
||||
if(flags & SDL_FULLSCREEN)
|
||||
SDL_ShowCursor(0);
|
||||
|
||||
/*
|
||||
* Load background image
|
||||
*/
|
||||
temp_image = IMG_Load("maxresdefault.jpg");
|
||||
if(!temp_image)
|
||||
{
|
||||
fprintf(stderr, "Could not load background!\n");
|
||||
exit(-1);
|
||||
}
|
||||
back = SDL_DisplayFormat(temp_image);
|
||||
SDL_FreeSurface(temp_image);
|
||||
|
||||
/*
|
||||
* Load logo
|
||||
*/
|
||||
temp_image = SDL_LoadBMP("logo.bmp");
|
||||
if(!temp_image)
|
||||
{
|
||||
fprintf(stderr, "Could not load logo!\n");
|
||||
exit(-1);
|
||||
}
|
||||
SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
|
||||
SDL_MapRGB(temp_image->format, 255, 0, 255));
|
||||
logo = SDL_DisplayFormat(temp_image);
|
||||
SDL_FreeSurface(temp_image);
|
||||
|
||||
/*
|
||||
* Load font
|
||||
*/
|
||||
temp_image = SDL_LoadBMP("font7x10.bmp");
|
||||
if(!temp_image)
|
||||
{
|
||||
fprintf(stderr, "Could not load font!\n");
|
||||
exit(-1);
|
||||
}
|
||||
SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
|
||||
SDL_MapRGB(temp_image->format, 255, 0, 255));
|
||||
font = SDL_DisplayFormat(temp_image);
|
||||
SDL_FreeSurface(temp_image);
|
||||
|
||||
temp_image = SDL_LoadBMP("font7x10-hex.bmp");
|
||||
if(!temp_image)
|
||||
{
|
||||
fprintf(stderr, "Could not load hex font!\n");
|
||||
exit(-1);
|
||||
}
|
||||
SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
|
||||
SDL_MapRGB(temp_image->format, 255, 0, 255));
|
||||
font_hex = SDL_DisplayFormat(temp_image);
|
||||
SDL_FreeSurface(temp_image);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
char name[32];
|
||||
sprintf(name, "mouse%d.png", i);
|
||||
temp_image = IMG_Load(name);
|
||||
if(!temp_image)
|
||||
{
|
||||
fprintf(stderr, "Could not load %s!\n", name);
|
||||
exit(-1);
|
||||
}
|
||||
//mouse[i] = SDL_DisplayFormat(temp_image);
|
||||
//SDL_FreeSurface(temp_image);
|
||||
mouse[i] = temp_image; // Keep alpha
|
||||
}
|
||||
|
||||
last_avg_tick = last_tick = SDL_GetTicks();
|
||||
|
||||
float gyroX = SCREEN_W/2, gyroY = SCREEN_H/2;
|
||||
|
||||
while(1)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
||||
/* Timing */
|
||||
tick = SDL_GetTicks();
|
||||
dt = (tick - last_tick) * 0.001f;
|
||||
last_tick = tick;
|
||||
|
||||
if( bpp == 32 )
|
||||
SDL_FillRect(screen, NULL, 0); // Clear alpha channel
|
||||
|
||||
/* Background image */
|
||||
tiled_back(back, screen, x_offs>>11, y_offs>>11);
|
||||
|
||||
/* FPS counter */
|
||||
if(tick > fps_start + 1000)
|
||||
{
|
||||
fps = (float)fps_count * 1000.0 / (tick - fps_start);
|
||||
fps_count = 0;
|
||||
fps_start = tick;
|
||||
}
|
||||
|
||||
print_num(screen, font, screen->w-37, screen->h-12, fps);
|
||||
++fps_count;
|
||||
|
||||
|
||||
r.x = gyroX;
|
||||
r.y = gyroY;
|
||||
r.w = mouse[0]->w;
|
||||
r.h = mouse[0]->h;
|
||||
r.x -= r.w/2;
|
||||
r.y -= r.h/2;
|
||||
SDL_BlitSurface(mouse[0], NULL, screen, &r);
|
||||
|
||||
SDL_Flip(SDL_GetVideoSurface());
|
||||
|
||||
SDL_Event evt;
|
||||
while( SDL_PollEvent(&evt) )
|
||||
{
|
||||
if(evt.type == SDL_KEYUP || evt.type == SDL_KEYDOWN)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL key event: evt %s state %s key %4d %12s scancode %4d mod %2d unicode %d", evt.type == SDL_KEYUP ? "UP " : "DOWN" , evt.key.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)evt.key.keysym.sym, SDL_GetKeyName(evt.key.keysym.sym), (int)evt.key.keysym.scancode, (int)evt.key.keysym.mod, (int)evt.key.keysym.unicode);
|
||||
if(evt.key.keysym.sym == SDLK_ESCAPE)
|
||||
return 0;
|
||||
}
|
||||
if(evt.type == SDL_MOUSEBUTTONUP || evt.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL mouse button event: evt %s state %s button %d coords %d:%d", evt.type == SDL_MOUSEBUTTONUP ? "UP " : "DOWN" , evt.button.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)evt.button.button, (int)evt.button.x, (int)evt.button.y);
|
||||
gyroX = SCREEN_W/2;
|
||||
gyroY = SCREEN_H/2;
|
||||
}
|
||||
if(evt.type == SDL_VIDEORESIZE)
|
||||
__android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL resize event: %d x %d", evt.resize.w, evt.resize.h);
|
||||
if(evt.type == SDL_ACTIVEEVENT)
|
||||
__android_log_print(ANDROID_LOG_INFO, "Ballfield", "======= SDL active event: gain %d state %d", evt.active.gain, evt.active.state);
|
||||
// Android-specific events - accelerometer, multitoush, and on-screen joystick
|
||||
if( evt.type == SDL_JOYAXISMOTION )
|
||||
{
|
||||
if(evt.jaxis.which == 1 && evt.jaxis.axis == 2)
|
||||
gyroX += evt.jaxis.value / 50.0f;
|
||||
if(evt.jaxis.which == 1 && evt.jaxis.axis == 3)
|
||||
gyroY -= evt.jaxis.value / 50.0f;
|
||||
if(gyroX < 0)
|
||||
gyroX = 0;
|
||||
if(gyroX > SCREEN_W)
|
||||
gyroX = SCREEN_W;
|
||||
if(gyroY < 0)
|
||||
gyroY = 0;
|
||||
if(gyroY > SCREEN_H)
|
||||
gyroY = SCREEN_H;
|
||||
}
|
||||
}
|
||||
|
||||
/* Animate */
|
||||
/*
|
||||
x_speed = 500.0 * sin(t * 0.37);
|
||||
y_speed = 500.0 * sin(t * 0.53);
|
||||
z_speed = 400.0 * sin(t * 0.21);
|
||||
x_offs -= x_speed;
|
||||
y_offs -= y_speed;
|
||||
*/
|
||||
|
||||
t += dt;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(back);
|
||||
SDL_FreeSurface(logo);
|
||||
SDL_FreeSurface(font);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user