728 lines
21 KiB
Java
728 lines
21 KiB
Java
package com.fteqw;
|
|
|
|
import javax.microedition.khronos.egl.EGLContext;
|
|
import javax.microedition.khronos.egl.EGLDisplay;
|
|
import javax.microedition.khronos.egl.EGLConfig;
|
|
import javax.microedition.khronos.egl.EGL10;
|
|
import javax.microedition.khronos.opengles.GL10;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.os.Bundle;
|
|
import android.view.Window;
|
|
import android.view.WindowManager;
|
|
|
|
import android.opengl.GLSurfaceView;
|
|
import android.view.KeyEvent;
|
|
import android.view.MotionEvent;
|
|
import android.app.AlertDialog;
|
|
import android.content.DialogInterface;
|
|
|
|
import android.hardware.SensorManager;
|
|
import android.hardware.Sensor;
|
|
import android.hardware.SensorEvent;
|
|
import android.hardware.SensorEventListener;
|
|
|
|
import android.media.AudioFormat;
|
|
import android.media.AudioManager;
|
|
import android.media.AudioTrack;
|
|
import android.os.Environment;
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
|
import android.os.Vibrator;
|
|
|
|
public class FTEDroidActivity extends Activity
|
|
{
|
|
private static final int USE_GLES_VERSION = 1; //valid values: 1 or 2. If set to 2, it'll still fall back to 1 if gles2 isn't supported on this device.
|
|
|
|
private SensorManager sensorman;
|
|
private Sensor sensoracc;
|
|
private FTEView view;
|
|
float acc_x, acc_y, acc_z; /*might be some minor race condition on these*/
|
|
private String basedir, userdir;
|
|
|
|
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
|
|
{
|
|
int version;
|
|
public void setversion(FTEView view, int version)
|
|
{
|
|
this.version = version;
|
|
view.setEGLContextClientVersion(version);
|
|
}
|
|
public boolean CheckGLES2Support()
|
|
{
|
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
|
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
|
EGLConfig cfg;
|
|
int oldver = this.version;
|
|
|
|
int[] version = new int[2];
|
|
egl.eglInitialize(display, version);
|
|
|
|
this.version = 2;
|
|
cfg = chooseConfig(egl, display);
|
|
this.version = oldver;
|
|
|
|
int[] value = {0};
|
|
egl.eglGetConfigAttrib(display, cfg, EGL10.EGL_RENDERABLE_TYPE, value);
|
|
egl.eglTerminate(display);
|
|
return ((value[0] & 4) == 4);
|
|
}
|
|
|
|
@Override
|
|
public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display)
|
|
{
|
|
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
|
EGLConfig[] cfg = new EGLConfig[64];
|
|
int[] num_configs = {0};
|
|
int[] value = {0};
|
|
int i;
|
|
int[] attribs =
|
|
{
|
|
egl.EGL_RENDERABLE_TYPE, (version>=2?4:1)/*egl.EGL_OPENGL_ES2_BIT*/,
|
|
// egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
|
|
egl.EGL_BLUE_SIZE, 5,
|
|
egl.EGL_GREEN_SIZE, 6,
|
|
egl.EGL_RED_SIZE, 5,
|
|
egl.EGL_DEPTH_SIZE, 16,
|
|
// egl.EGL_STENCIL_SIZE, 8,
|
|
egl.EGL_NONE, egl.EGL_NONE
|
|
};
|
|
|
|
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
|
|
throw new IllegalArgumentException("eglChooseConfig failed");
|
|
|
|
if (num_configs[0] == 0)
|
|
{
|
|
attribs[1] = 1; //egl.EGL_RENDERABLE_TYPE, 1/*egl.EGL_OPENGL_ES_BIT*/,
|
|
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
|
|
throw new IllegalArgumentException("eglChooseConfig failed");
|
|
|
|
if (num_configs[0] == 0)
|
|
{
|
|
throw new IllegalArgumentException("eglChooseConfig didn't report any valid configs");
|
|
}
|
|
}
|
|
|
|
android.util.Log.i("FTEDroid", "Found " + num_configs[0] + " EGL configs.");
|
|
|
|
//try to find a gles2 context instead.
|
|
for (i = 0; i < num_configs[0]; i++)
|
|
{
|
|
android.util.Log.i("FTEDroid", "Config " + i + ":");
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RED_SIZE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_RED_SIZE " + value[0]);
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_GREEN_SIZE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_GREEN_SIZE " + value[0]);
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_BLUE_SIZE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_BLUE_SIZE " + value[0]);
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_DEPTH_SIZE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_DEPTH_SIZE " + value[0]);
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_STENCIL_SIZE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_STENCIL_SIZE " + value[0]);
|
|
|
|
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RENDERABLE_TYPE, value);
|
|
android.util.Log.i("FTEDroid", "EGL_RENDERABLE_TYPE " + value[0]);
|
|
|
|
if ((value[0] & 4) == 4)
|
|
{
|
|
android.util.Log.i("FTEDroid", "Found a GLES2 context!");
|
|
return cfg[i];
|
|
}
|
|
}
|
|
return cfg[0];
|
|
}
|
|
}
|
|
|
|
private class FTERenderer implements GLSurfaceView.Renderer
|
|
{
|
|
private boolean inited;
|
|
public int glesversion;
|
|
FTEDroidActivity act;
|
|
FTEView theview;
|
|
FTEEGLConfig cfgchooser;
|
|
int notifiedflags;
|
|
|
|
void updateGLESVersion()
|
|
{
|
|
if (FTEDroidEngine.getpreferedglesversion() < 2)
|
|
{
|
|
android.util.Log.i("FTEDroid", "Using GLES1");
|
|
this.glesversion = 1;
|
|
}
|
|
else if (android.os.Build.VERSION.SDK_INT >= 8) //could be 5 with setEGLContextFactory instead of setEGLContextClientVersion
|
|
{
|
|
if (cfgchooser.CheckGLES2Support())
|
|
{
|
|
android.util.Log.i("FTEDroid", "Support for GLES2 detected");
|
|
this.glesversion = 2;
|
|
cfgchooser.setversion(theview, this.glesversion);
|
|
}
|
|
else
|
|
{
|
|
android.util.Log.i("FTEDroid", "GLES2 not supported. Using GLES1.");
|
|
this.glesversion = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
android.util.Log.i("FTEDroid", "GLES2 requires android 2.2+");
|
|
this.glesversion = 1;
|
|
}
|
|
}
|
|
|
|
FTERenderer(FTEView view, FTEDroidActivity parent)
|
|
{
|
|
act = parent;
|
|
theview = view;
|
|
|
|
FTEDroidEngine.init(0, 0, 0, basedir, userdir);
|
|
inited = true;
|
|
|
|
cfgchooser = new FTEEGLConfig();
|
|
// theview.setEGLConfigChooser(cfgchooser);
|
|
updateGLESVersion();
|
|
}
|
|
|
|
@Override
|
|
public void onDrawFrame(GL10 gl)
|
|
{
|
|
if (inited == true)
|
|
{
|
|
int flags;
|
|
flags = FTEDroidEngine.frame(act.acc_x, act.acc_y, act.acc_z);
|
|
if (flags != notifiedflags)
|
|
{
|
|
if (((flags ^ notifiedflags) & 1) != 0)
|
|
{
|
|
final int fl = flags;
|
|
Runnable r = new Runnable()
|
|
{ //doing this on the ui thread because android sucks.
|
|
public void run()
|
|
{
|
|
InputMethodManager im = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
if (im != null)
|
|
{
|
|
if ((fl & 1) != 0)
|
|
{
|
|
// getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
|
im.showSoftInput(theview, 0);//InputMethodManager.SHOW_FORCED);
|
|
}
|
|
else
|
|
{
|
|
// getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
|
im.hideSoftInputFromWindow(theview.getWindowToken(), 0);
|
|
}
|
|
}
|
|
else
|
|
android.util.Log.i("FTEDroid", "IMM failed");
|
|
}
|
|
};
|
|
act.runOnUiThread(r);
|
|
}
|
|
if (((flags ^ notifiedflags) & 2) != 0)
|
|
{
|
|
int dur = FTEDroidEngine.getvibrateduration();
|
|
flags &= ~2;
|
|
Vibrator vib = (Vibrator) act.getSystemService(Context.VIBRATOR_SERVICE);
|
|
if (vib != null)
|
|
{
|
|
android.util.Log.i("FTEDroid", "Vibrate " + dur + "ms");
|
|
vib.vibrate(dur);
|
|
}
|
|
else
|
|
android.util.Log.i("FTEDroid", "No vibrator device");
|
|
}
|
|
if (((flags ^ notifiedflags) & 4) != 0)
|
|
{
|
|
final int fl = flags;
|
|
Runnable r = new Runnable()
|
|
{
|
|
public void run()
|
|
{
|
|
if ((fl & 4) != 0)
|
|
act.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
else
|
|
act.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
}
|
|
};
|
|
act.runOnUiThread(r);
|
|
}
|
|
if (((flags ^ notifiedflags) & 8) != 0)
|
|
{
|
|
final String errormsg = FTEDroidEngine.geterrormessage();
|
|
|
|
inited = false;
|
|
|
|
if (errormsg == "")
|
|
{
|
|
finish();
|
|
System.exit(0);
|
|
}
|
|
|
|
//8 means sys error
|
|
Runnable r = new Runnable()
|
|
{
|
|
public void run()
|
|
{
|
|
theview.setVisibility(theview.GONE);
|
|
AlertDialog ad = new AlertDialog.Builder(act).create();
|
|
ad.setTitle("FTE ERROR");
|
|
ad.setMessage(errormsg);
|
|
ad.setCancelable(false);
|
|
ad.setButton("Ok", new DialogInterface.OnClickListener()
|
|
{
|
|
public void onClick(DialogInterface dialog, int which)
|
|
{
|
|
finish();
|
|
System.exit(0);
|
|
}
|
|
}
|
|
);
|
|
ad.show();
|
|
}
|
|
};
|
|
act.runOnUiThread(r);
|
|
}
|
|
if (((flags ^ notifiedflags) & 16) != 0)
|
|
{
|
|
//16 means orientation cvar change
|
|
Runnable r = new Runnable()
|
|
{
|
|
public void run()
|
|
{
|
|
String ors = FTEDroidEngine.getpreferedorientation();
|
|
int ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR;
|
|
if (ors.equalsIgnoreCase("unspecified"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
|
else if (ors.equalsIgnoreCase("landscape"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
|
else if (ors.equalsIgnoreCase("portrait"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
|
else if (ors.equalsIgnoreCase("user"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
|
|
else if (ors.equalsIgnoreCase("behind"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
|
|
else if (ors.equalsIgnoreCase("sensor"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR;
|
|
else if (ors.equalsIgnoreCase("nosensor"))
|
|
ori = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
|
|
//the following are api level 9+
|
|
else if (ors.equalsIgnoreCase("sensorlandscape"))
|
|
ori = 6;//android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
|
|
else if (ors.equalsIgnoreCase("sensorportrait"))
|
|
ori = 7;//android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
|
|
else if (ors.equalsIgnoreCase("reverselandscape"))
|
|
ori = 8;//android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
|
else if (ors.equalsIgnoreCase("reverseportrait"))
|
|
ori = 9;//android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
|
else if (ors.equalsIgnoreCase("fullsensor"))
|
|
ori = 10;//android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
|
|
android.util.Log.i("FTEDroid", "Orientation changed to " + ori + " (" + ors + ").");
|
|
act.setRequestedOrientation(ori);
|
|
}
|
|
};
|
|
act.runOnUiThread(r);
|
|
}
|
|
if (((flags ^ notifiedflags) & 32) != 0)
|
|
{
|
|
if ((flags & 32) != 0)
|
|
view.audioInit(FTEDroidEngine.audioinfo(0), FTEDroidEngine.audioinfo(1), FTEDroidEngine.audioinfo(2));
|
|
else
|
|
view.audioStop();
|
|
}
|
|
|
|
//clear anything which is an impulse
|
|
notifiedflags = flags;
|
|
}
|
|
}
|
|
}
|
|
@Override
|
|
public void onSurfaceChanged(GL10 gl, int width, int height)
|
|
{
|
|
android.util.Log.i("FTEDroid", "Surface changed, now " + width + " by " + height + ".");
|
|
FTEDroidEngine.init(width, height, glesversion, basedir, userdir);
|
|
inited = true;
|
|
}
|
|
@Override
|
|
public void onSurfaceCreated(GL10 gl, EGLConfig config)
|
|
{
|
|
FTEDroidEngine.newglcontext();
|
|
}
|
|
}
|
|
|
|
private class FTEView extends GLSurfaceView implements SensorEventListener
|
|
{
|
|
private final FTERenderer rndr;
|
|
|
|
private audiothreadclass audiothread;
|
|
private class audiothreadclass extends Thread
|
|
{
|
|
boolean timetodie;
|
|
int schannels;
|
|
int sspeed;
|
|
int sbits;
|
|
@Override
|
|
public void run()
|
|
{
|
|
byte[] audbuf = new byte[2048];
|
|
int avail;
|
|
AudioTrack at;
|
|
|
|
int chans;
|
|
try
|
|
{
|
|
if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+
|
|
chans = AudioFormat.CHANNEL_OUT_7POINT1;
|
|
else if (schannels >= 6)
|
|
chans = AudioFormat.CHANNEL_OUT_5POINT1;
|
|
else if (schannels >= 4)
|
|
chans = AudioFormat.CHANNEL_OUT_QUAD;
|
|
else if (schannels >= 2)
|
|
chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
|
|
else
|
|
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
|
int enc = (sbits == 8)?AudioFormat.ENCODING_PCM_8BIT:AudioFormat.ENCODING_PCM_16BIT;
|
|
|
|
int sz = 2*AudioTrack.getMinBufferSize(sspeed, chans, enc);
|
|
|
|
// if (sz < sspeed * 0.05)
|
|
// sz = sspeed * 0.05;
|
|
|
|
at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, chans, enc, sz, AudioTrack.MODE_STREAM);
|
|
}
|
|
catch(IllegalArgumentException e)
|
|
{
|
|
//fixme: tell the engine that its bad and that it should configure some different audio attributes, instead of simply muting.
|
|
return;
|
|
}
|
|
|
|
at.setStereoVolume(1, 1);
|
|
at.play();
|
|
|
|
while(!timetodie)
|
|
{
|
|
avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
|
|
at.write(audbuf, 0, avail);
|
|
}
|
|
|
|
at.stop();
|
|
}
|
|
public void killoff()
|
|
{
|
|
timetodie = true;
|
|
try
|
|
{
|
|
join();
|
|
}
|
|
catch(InterruptedException e)
|
|
{
|
|
}
|
|
timetodie = false;
|
|
}
|
|
};
|
|
|
|
private void audioInit(int sspeed, int schannels, int sbits)
|
|
{
|
|
if (audiothread == null)
|
|
{
|
|
audiothread = new audiothreadclass();
|
|
audiothread.schannels = schannels;
|
|
audiothread.sspeed = sspeed;
|
|
audiothread.sbits = sbits;
|
|
audiothread.start();
|
|
}
|
|
}
|
|
public void audioStop()
|
|
{
|
|
if (audiothread != null)
|
|
{
|
|
audiothread.killoff();
|
|
audiothread = null;
|
|
}
|
|
}
|
|
public void audioResume()
|
|
{
|
|
if (audiothread != null)
|
|
{
|
|
audiothread.killoff();
|
|
audiothread.start();
|
|
}
|
|
}
|
|
|
|
private FTELegacyInputEvent inputevent;
|
|
class FTEMultiTouchInputEvent extends FTELegacyInputEvent
|
|
{
|
|
/*Requires API level 5+ (android 2.0+)*/
|
|
private void domove(MotionEvent event)
|
|
{
|
|
final int pointerCount = event.getPointerCount();
|
|
int i;
|
|
for (i = 0; i < pointerCount; i++)
|
|
FTEDroidEngine.motion(0, event.getPointerId(i), event.getX(i), event.getY(i), event.getSize(i));
|
|
}
|
|
|
|
public boolean go(MotionEvent event)
|
|
{
|
|
int id;
|
|
float x, y, size;
|
|
final int act = event.getAction();
|
|
|
|
domove(event);
|
|
|
|
switch(act & event.ACTION_MASK)
|
|
{
|
|
case MotionEvent.ACTION_DOWN:
|
|
case MotionEvent.ACTION_POINTER_DOWN:
|
|
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
|
x = event.getX(id);
|
|
y = event.getY(id);
|
|
size = event.getSize(id);
|
|
id = event.getPointerId(id);
|
|
FTEDroidEngine.motion(1, id, x, y, size);
|
|
break;
|
|
case MotionEvent.ACTION_UP:
|
|
case MotionEvent.ACTION_POINTER_UP:
|
|
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
|
x = event.getX(id);
|
|
y = event.getY(id);
|
|
size = event.getSize(id);
|
|
id = event.getPointerId(id);
|
|
FTEDroidEngine.motion(2, id, x, y, size);
|
|
break;
|
|
case MotionEvent.ACTION_MOVE:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
class FTELegacyInputEvent
|
|
{
|
|
public boolean go(MotionEvent event)
|
|
{
|
|
final int act = event.getAction();
|
|
final float x = event.getX();
|
|
final float y = event.getY();
|
|
final float size = event.getSize();
|
|
|
|
FTEDroidEngine.motion(0, 0, x, y, size);
|
|
|
|
switch(act)
|
|
{
|
|
case MotionEvent.ACTION_DOWN:
|
|
FTEDroidEngine.motion(1, 0, x, y, size);
|
|
break;
|
|
case MotionEvent.ACTION_UP:
|
|
FTEDroidEngine.motion(2, 0, x, y, size);
|
|
break;
|
|
case MotionEvent.ACTION_MOVE:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public FTEView(FTEDroidActivity context)
|
|
{
|
|
super(context);
|
|
|
|
if (android.os.Build.VERSION.SDK_INT >= 5)
|
|
inputevent = new FTEMultiTouchInputEvent();
|
|
else
|
|
inputevent = new FTELegacyInputEvent();
|
|
|
|
rndr = new FTERenderer(this, context);
|
|
setRenderer(rndr);
|
|
setFocusable(true);
|
|
setFocusableInTouchMode(true);
|
|
}
|
|
|
|
private void sendKey(final boolean presseddown, final int qcode, final int unicode)
|
|
{
|
|
FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode);
|
|
}
|
|
@Override
|
|
public boolean onTouchEvent(MotionEvent event)
|
|
{
|
|
return inputevent.go(event);
|
|
}
|
|
/*
|
|
@Override
|
|
public boolean onTrackballEvent(MotionEvent event)
|
|
{
|
|
int act = event.getAction();
|
|
float x = event.getX();
|
|
float y = event.getY();
|
|
}
|
|
*/
|
|
private static final int K_ENTER = 13;
|
|
private static final int K_ESCAPE = 27;
|
|
private static final int K_DEL = 127;
|
|
private static final int K_POWER = 130;
|
|
private static final int K_UPARROW = 132;
|
|
private static final int K_DOWNARROW = 133;
|
|
private static final int K_LEFTARROW = 134;
|
|
private static final int K_RIGHTARROW = 135;
|
|
private static final int K_APP = 241;
|
|
private static final int K_SEARCH = 242;
|
|
private static final int K_VOLUP = 243;
|
|
private static final int K_VOLDOWN = 244;
|
|
private int mapKey(int acode, int unicode)
|
|
{
|
|
switch(acode)
|
|
{
|
|
case KeyEvent.KEYCODE_DPAD_UP:
|
|
return K_UPARROW;
|
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
|
return K_DOWNARROW;
|
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
|
return K_LEFTARROW;
|
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
|
return K_RIGHTARROW;
|
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
return K_ENTER;
|
|
case KeyEvent.KEYCODE_BACK:
|
|
return K_ESCAPE; //escape, cannot be rebound
|
|
case KeyEvent.KEYCODE_MENU:
|
|
return K_APP; //"app"
|
|
case KeyEvent.KEYCODE_DEL:
|
|
return K_DEL; //"del"
|
|
case KeyEvent.KEYCODE_SEARCH:
|
|
return K_SEARCH; //"search"
|
|
case KeyEvent.KEYCODE_POWER:
|
|
return K_POWER; //"power"
|
|
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
|
return K_VOLDOWN; //"voldown"
|
|
case KeyEvent.KEYCODE_VOLUME_UP:
|
|
return K_VOLUP; //"volup"
|
|
default:
|
|
if (unicode < 128)
|
|
return Character.toLowerCase(unicode);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public boolean onKeyDown(int keyCode, KeyEvent event)
|
|
{
|
|
int uc = event.getUnicodeChar();
|
|
sendKey(true, mapKey(keyCode, uc), uc);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onKeyUp(int keyCode, KeyEvent event)
|
|
{
|
|
int uc = event.getUnicodeChar();
|
|
sendKey(false, mapKey(keyCode, uc), uc);
|
|
return true;
|
|
}
|
|
|
|
public void onAccuracyChanged(Sensor sensor, int accuracy)
|
|
{
|
|
}
|
|
|
|
public void onSensorChanged(final SensorEvent event)
|
|
{
|
|
acc_x = event.values[0];
|
|
acc_y = event.values[1];
|
|
acc_z = event.values[2];
|
|
}
|
|
}
|
|
|
|
private boolean runningintheemulator()
|
|
{
|
|
android.util.Log.i("FTEDroid", "model: " + android.os.Build.MODEL + " product: " + android.os.Build.PRODUCT + " device: " + android.os.Build.DEVICE);
|
|
return android.os.Build.MODEL.equals("sdk") && android.os.Build.PRODUCT.equals("sdk") && android.os.Build.DEVICE.equals("generic");
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState)
|
|
{
|
|
android.util.Log.i("FTEDroid", "onCreate");
|
|
|
|
try
|
|
{
|
|
String packagename = this.getComponentName().getPackageName(); //"com.fteqw", but not hardcoded.
|
|
android.util.Log.i("FTEDroid", "Installed in package \"" + packagename + "\".");
|
|
android.content.pm.PackageInfo info = this.getPackageManager().getPackageInfo(packagename, 0);
|
|
basedir = info.applicationInfo.sourceDir;
|
|
}
|
|
catch(android.content.pm.PackageManager.NameNotFoundException e)
|
|
{
|
|
/*oh well, can just use the homedir instead*/
|
|
}
|
|
// try
|
|
// {
|
|
userdir = Environment.getExternalStorageDirectory().getPath() + "/fte";
|
|
// }
|
|
// catch(foo)
|
|
// {
|
|
// }
|
|
android.util.Log.i("FTEDroid", "Base dir is \"" + basedir + "\".");
|
|
android.util.Log.i("FTEDroid", "User dir is \"" + userdir + "\".");
|
|
|
|
//go full-screen
|
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
android.util.Log.i("FTEDroid", "create view");
|
|
view = new FTEView(this);
|
|
setContentView(view);
|
|
|
|
|
|
if (runningintheemulator())
|
|
{
|
|
android.util.Log.i("FTEDroid", "emulator detected - skipping sensors to avoid emulator bugs");
|
|
sensorman = null;
|
|
}
|
|
else
|
|
{
|
|
android.util.Log.i("FTEDroid", "init sensor manager");
|
|
sensorman = (SensorManager)getSystemService(SENSOR_SERVICE);
|
|
}
|
|
if (sensorman != null)
|
|
{
|
|
android.util.Log.i("FTEDroid", "init accelerometer");
|
|
sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
|
}
|
|
android.util.Log.i("FTEDroid", "done");
|
|
}
|
|
|
|
@Override
|
|
protected void onResume()
|
|
{
|
|
super.onResume();
|
|
if (sensorman != null && sensoracc != null)
|
|
sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME);
|
|
|
|
view.audioResume();
|
|
}
|
|
|
|
@Override
|
|
protected void onStop()
|
|
{
|
|
if (sensorman != null && sensoracc != null)
|
|
sensorman.unregisterListener(view);
|
|
view.audioStop();
|
|
super.onStop();
|
|
}
|
|
|
|
@Override
|
|
protected void onPause()
|
|
{
|
|
if (sensorman != null && sensoracc != null)
|
|
sensorman.unregisterListener(view);
|
|
view.audioStop();
|
|
super.onPause();
|
|
}
|
|
}
|