Forget some files... Here they are.

This commit is contained in:
Gerhard Stein
2013-10-14 18:50:23 +02:00
parent ea4a29e4de
commit 16404b2e2f
12 changed files with 7365 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.os.Vibrator;
import android.hardware.SensorManager;
import android.hardware.SensorEventListener;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.util.Log;
import android.widget.TextView;
class AccelerometerReader implements SensorEventListener
{
private SensorManager _manager = null;
public boolean openedBySDL = false;
public static final GyroscopeListener gyro = new GyroscopeListener();
public AccelerometerReader(Activity context)
{
_manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
}
public synchronized void stop()
{
if( _manager != null )
{
Log.i("SDL", "libSDL: stopping accelerometer/gyroscope");
_manager.unregisterListener(this);
_manager.unregisterListener(gyro);
}
}
public synchronized void start()
{
if( (Globals.UseAccelerometerAsArrowKeys || Globals.AppUsesAccelerometer) &&
_manager != null && _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null )
{
Log.i("SDL", "libSDL: starting accelerometer");
_manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
if( Globals.AppUsesGyroscope && _manager != null && _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null )
{
Log.i("SDL", "libSDL: starting gyroscope");
_manager.registerListener(gyro, _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
}
public void onSensorChanged(SensorEvent event)
{
if( Globals.HorizontalOrientation )
nativeAccelerometer(event.values[1], -event.values[0], event.values[2]);
else
nativeAccelerometer(event.values[0], event.values[1], event.values[2]); // TODO: not tested!
}
public void onAccuracyChanged(Sensor s, int a)
{
}
static class GyroscopeListener implements SensorEventListener
{
public float x1, x2, xc, y1, y2, yc, z1, z2, zc;
public GyroscopeListener()
{
}
public void onSensorChanged(SensorEvent event)
{
// TODO: vertical orientation
//if( Globals.HorizontalOrientation )
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 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);
private static native void nativeGyroscope(float X, float Y, float Z);
}

View File

@@ -0,0 +1,50 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.view.View;
class Advertisement
{
MainActivity parent;
public Advertisement(MainActivity p)
{
parent = p;
}
public View getView()
{
return null;
}
public void requestNewAd()
{
}
}

307
project/javaSDL2/Audio.java Normal file
View File

@@ -0,0 +1,307 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.media.AudioTrack;
import android.media.AudioManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import java.io.*;
import android.util.Log;
import java.util.concurrent.Semaphore;
class AudioThread
{
private MainActivity mParent;
private AudioTrack mAudio;
private byte[] mAudioBuffer;
private int mVirtualBufSize;
public AudioThread(MainActivity parent)
{
mParent = parent;
mAudio = null;
mAudioBuffer = null;
//nativeAudioInitJavaCallbacks();
}
public int fillBuffer()
{
if( mParent.isPaused() )
{
try{
Thread.sleep(500);
} catch (InterruptedException e) {}
}
else
{
//if( Globals.AudioBufferConfig == 0 ) // Gives too much spam to logcat, makes things worse
// mAudio.flush();
mAudio.write( mAudioBuffer, 0, mVirtualBufSize );
}
return 1;
}
public int initAudio(int rate, int channels, int encoding, int bufSize)
{
if( mAudio == null )
{
channels = ( channels == 1 ) ? AudioFormat.CHANNEL_CONFIGURATION_MONO :
AudioFormat.CHANNEL_CONFIGURATION_STEREO;
encoding = ( encoding == 1 ) ? AudioFormat.ENCODING_PCM_16BIT :
AudioFormat.ENCODING_PCM_8BIT;
mVirtualBufSize = bufSize;
if( AudioTrack.getMinBufferSize( rate, channels, encoding ) > bufSize )
bufSize = AudioTrack.getMinBufferSize( rate, channels, encoding );
if(Globals.AudioBufferConfig != 0) { // application's choice - use minimal buffer
bufSize = (int)((float)bufSize * (((float)(Globals.AudioBufferConfig - 1) * 2.5f) + 1.0f));
mVirtualBufSize = bufSize;
}
mAudioBuffer = new byte[bufSize];
mAudio = new AudioTrack(AudioManager.STREAM_MUSIC,
rate,
channels,
encoding,
bufSize,
AudioTrack.MODE_STREAM );
mAudio.play();
}
return mVirtualBufSize;
}
public byte[] getBuffer()
{
return mAudioBuffer;
}
public int deinitAudio()
{
if( mAudio != null )
{
mAudio.stop();
mAudio.release();
mAudio = null;
}
mAudioBuffer = null;
return 1;
}
public int initAudioThread()
{
// Make audio thread priority higher so audio thread won't get underrun
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
return 1;
}
public int pauseAudioPlayback()
{
if( mAudio != null )
{
mAudio.pause();
}
if( mRecordThread != null )
{
mRecordThread.pauseRecording();
}
return 1;
}
public int resumeAudioPlayback()
{
if( mAudio != null )
{
mAudio.play();
}
if( mRecordThread != null )
{
mRecordThread.resumeRecording();
}
return 1;
}
private native int nativeAudioInitJavaCallbacks();
// ----- Audio recording -----
private RecordingThread mRecordThread = null;
private AudioRecord mRecorder = null;
private int mRecorderBufferSize = 0;
private byte[] startRecording(int rate, int channels, int encoding, int bufsize)
{
if( mRecordThread == null )
{
mRecordThread = new RecordingThread();
mRecordThread.start();
}
if( !mRecordThread.isStopped() )
{
Log.i("SDL", "SDL: error: application already opened audio recording device");
return null;
}
mRecordThread.init(bufsize);
int channelConfig = ( channels == 1 ) ? AudioFormat.CHANNEL_IN_MONO :
AudioFormat.CHANNEL_IN_STEREO;
int encodingConfig = ( encoding == 1 ) ? AudioFormat.ENCODING_PCM_16BIT :
AudioFormat.ENCODING_PCM_8BIT;
int minBufDevice = AudioRecord.getMinBufferSize(rate, channelConfig, encodingConfig);
int minBufferSize = Math.max(bufsize * 8, minBufDevice + (bufsize - (minBufDevice % bufsize)));
Log.i("SDL", "SDL: app opened recording device, rate " + rate + " channels " + channels + " sample size " + (encoding+1) + " bufsize " + bufsize + " internal bufsize " + minBufferSize);
if( mRecorder == null || mRecorder.getSampleRate() != rate ||
mRecorder.getChannelCount() != channels ||
mRecorder.getAudioFormat() != encodingConfig ||
mRecorderBufferSize != minBufferSize )
{
if( mRecorder != null )
mRecorder.release();
mRecorder = null;
try {
mRecorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, encodingConfig, minBufferSize);
mRecorderBufferSize = minBufferSize;
} catch (IllegalArgumentException e) {
Log.i("SDL", "SDL: error: failed to open recording device!");
return null;
}
}
else
{
Log.i("SDL", "SDL: reusing old recording device");
}
mRecordThread.startRecording();
return mRecordThread.mRecordBuffer;
}
private void stopRecording()
{
if( mRecordThread == null || mRecordThread.isStopped() )
{
Log.i("SDL", "SDL: error: application already closed audio recording device");
return;
}
mRecordThread.stopRecording();
Log.i("SDL", "SDL: app closed recording device");
}
private class RecordingThread extends Thread
{
private boolean stopped = true;
byte[] mRecordBuffer;
private Semaphore waitStarted = new Semaphore(0);
private boolean sleep = false;
RecordingThread()
{
super();
}
void init(int bufsize)
{
if( mRecordBuffer == null || mRecordBuffer.length != bufsize )
mRecordBuffer = new byte[bufsize];
}
public void run()
{
while( true )
{
waitStarted.acquireUninterruptibly();
waitStarted.drainPermits();
stopped = false;
sleep = false;
while( !sleep )
{
int got = mRecorder.read(mRecordBuffer, 0, mRecordBuffer.length);
if( got != mRecordBuffer.length )
{
// Audio is stopped here, sleep a bit.
try{
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
else
{
//Log.i("SDL", "SDL: nativeAudioRecordCallback with len " + mRecordBuffer.length);
nativeAudioRecordCallback();
//Log.i("SDL", "SDL: nativeAudioRecordCallback returned");
}
}
stopped = true;
mRecorder.stop();
}
}
public void startRecording()
{
mRecorder.startRecording();
waitStarted.release();
}
public void stopRecording()
{
sleep = true;
while( !stopped )
{
try{
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
public void pauseRecording()
{
if( !stopped )
mRecorder.stop();
}
public void resumeRecording()
{
if( !stopped )
mRecorder.startRecording();
}
public boolean isStopped()
{
return stopped;
}
}
private native void nativeAudioRecordCallback();
}

View File

@@ -0,0 +1,758 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.os.Environment;
import android.widget.TextView;
import org.apache.http.client.methods.*;
import org.apache.http.*;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.conn.*;
import org.apache.http.conn.params.*;
import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.*;
import org.apache.http.impl.*;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.SingleClientConnManager;
import java.security.cert.*;
import java.security.SecureRandom;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import java.util.zip.*;
import java.io.*;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.Context;
import android.content.res.Resources;
import java.lang.String;
import android.text.SpannedString;
import android.app.AlertDialog;
import android.content.DialogInterface;
class CountingInputStream extends BufferedInputStream
{
private long bytesReadMark = 0;
private long bytesRead = 0;
public CountingInputStream(InputStream in, int size) {
super(in, size);
}
public CountingInputStream(InputStream in) {
super(in);
}
public long getBytesRead() {
return bytesRead;
}
public synchronized int read() throws IOException {
int read = super.read();
if (read >= 0) {
bytesRead++;
}
return read;
}
public synchronized int read(byte[] b, int off, int len) throws IOException {
int read = super.read(b, off, len);
if (read >= 0) {
bytesRead += read;
}
return read;
}
public synchronized long skip(long n) throws IOException {
long skipped = super.skip(n);
if (skipped >= 0) {
bytesRead += skipped;
}
return skipped;
}
public synchronized void mark(int readlimit) {
super.mark(readlimit);
bytesReadMark = bytesRead;
}
public synchronized void reset() throws IOException {
super.reset();
bytesRead = bytesReadMark;
}
}
class DataDownloader extends Thread
{
public static final String DOWNLOAD_FLAG_FILENAME = "libsdl-DownloadFinished-";
class StatusWriter
{
private TextView Status;
private MainActivity Parent;
private SpannedString oldText = new SpannedString("");
public StatusWriter( TextView _Status, MainActivity _Parent )
{
Status = _Status;
Parent = _Parent;
}
public void setParent( TextView _Status, MainActivity _Parent )
{
synchronized(DataDownloader.this) {
Status = _Status;
Parent = _Parent;
setText( oldText.toString() );
}
}
public void setText(final String str)
{
class Callback implements Runnable
{
public TextView Status;
public SpannedString text;
public void run()
{
Status.setText(text);
}
}
synchronized(DataDownloader.this) {
Callback cb = new Callback();
oldText = new SpannedString(str);
cb.text = new SpannedString(str);
cb.Status = Status;
if( Parent != null && Status != null )
Parent.runOnUiThread(cb);
}
}
}
public DataDownloader( MainActivity _Parent, TextView _Status )
{
Parent = _Parent;
Status = new StatusWriter( _Status, _Parent );
//Status.setText( "Connecting to " + Globals.DataDownloadUrl );
outFilesDir = Globals.DataDir;
DownloadComplete = false;
this.start();
}
public void setStatusField(TextView _Status)
{
synchronized(this) {
Status.setParent( _Status, Parent );
}
}
@Override
public void run()
{
Parent.keyListener = new BackKeyListener(Parent);
String [] downloadFiles = Globals.DataDownloadUrl;
int total = 0;
int count = 0;
for( int i = 0; i < downloadFiles.length; i++ )
{
if( downloadFiles[i].length() > 0 &&
( Globals.OptionalDataDownload.length > i && Globals.OptionalDataDownload[i] ) ||
( Globals.OptionalDataDownload.length <= i && downloadFiles[i].indexOf("!") == 0 ) )
total += 1;
}
for( int i = 0; i < downloadFiles.length; i++ )
{
if( downloadFiles[i].length() > 0 &&
( Globals.OptionalDataDownload.length > i && Globals.OptionalDataDownload[i] ) ||
( Globals.OptionalDataDownload.length <= i && downloadFiles[i].indexOf("!") == 0 ) )
{
if( ! DownloadDataFile(downloadFiles[i], DOWNLOAD_FLAG_FILENAME + String.valueOf(i) + ".flag", count+1, total, i) )
{
DownloadFailed = true;
return;
}
count += 1;
}
}
DownloadComplete = true;
Parent.keyListener = null;
initParent();
}
public boolean DownloadDataFile(final String DataDownloadUrl, final String DownloadFlagFileName, int downloadCount, int downloadTotal, int downloadIndex)
{
DownloadCanBeResumed = false;
Resources res = Parent.getResources();
String [] downloadUrls = DataDownloadUrl.split("[|]");
if( downloadUrls.length < 2 )
{
Log.i("SDL", "Error: download string invalid: '" + DataDownloadUrl + "', your AndroidAppSettigns.cfg is broken");
Status.setText( res.getString(R.string.error_dl_from, DataDownloadUrl) );
return false;
}
boolean forceOverwrite = false;
String path = getOutFilePath(DownloadFlagFileName);
InputStream checkFile = null;
try {
checkFile = new FileInputStream( path );
} catch( FileNotFoundException e ) {
} catch( SecurityException e ) { };
if( checkFile != null )
{
try {
byte b[] = new byte[ Globals.DataDownloadUrl[downloadIndex].getBytes("UTF-8").length + 1 ];
int readed = checkFile.read(b);
String compare = "";
if( readed > 0 )
compare = new String( b, 0, readed, "UTF-8" );
boolean matched = false;
//Log.i("SDL", "Read URL: '" + compare + "'");
for( int i = 1; i < downloadUrls.length; i++ )
{
//Log.i("SDL", "Comparing: '" + downloadUrls[i] + "'");
if( compare.compareTo(downloadUrls[i]) == 0 )
matched = true;
}
//Log.i("SDL", "Matched: " + String.valueOf(matched));
if( ! matched )
throw new IOException();
Status.setText( res.getString(R.string.download_unneeded) );
return true;
} catch ( IOException e ) {
forceOverwrite = true;
new File(path).delete();
}
}
checkFile = null;
// Create output directory (not necessary for phone storage)
Log.i("SDL", "Downloading data to: '" + outFilesDir + "'");
try {
File outDir = new File( outFilesDir );
if( !(outDir.exists() && outDir.isDirectory()) )
outDir.mkdirs();
OutputStream out = new FileOutputStream( getOutFilePath(".nomedia") );
out.flush();
out.close();
}
catch( SecurityException e ) {}
catch( FileNotFoundException e ) {}
catch( IOException e ) {};
HttpResponse response = null, responseError = null;
HttpGet request;
long totalLen = 0;
CountingInputStream stream;
byte[] buf = new byte[16384];
boolean DoNotUnzip = false;
boolean FileInAssets = false;
String url = "";
long partialDownloadLen = 0;
int downloadUrlIndex = 1;
while( downloadUrlIndex < downloadUrls.length )
{
Log.i("SDL", "Processing download " + downloadUrls[downloadUrlIndex]);
url = new String(downloadUrls[downloadUrlIndex]);
DoNotUnzip = false;
if(url.indexOf(":") == 0)
{
path = getOutFilePath(url.substring( 1, url.indexOf(":", 1) ));
url = url.substring( url.indexOf(":", 1) + 1 );
DoNotUnzip = true;
DownloadCanBeResumed = true;
File partialDownload = new File( path );
if( partialDownload.exists() && !partialDownload.isDirectory() && !forceOverwrite )
partialDownloadLen = partialDownload.length();
}
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.connecting_to, url) );
if( url.indexOf("http://") == -1 && url.indexOf("https://") == -1 ) // File inside assets
{
InputStream stream1 = null;
try {
stream1 = Parent.getAssets().open(url);
stream1.close();
} catch( Exception e ) {
try {
stream1 = Parent.getAssets().open(url + "000");
stream1.close();
} catch( Exception ee ) {
Log.i("SDL", "Failed to open file in assets: " + url);
downloadUrlIndex++;
continue;
}
}
FileInAssets = true;
Log.i("SDL", "Fetching file from assets: " + url);
break;
}
else
{
Log.i("SDL", "Connecting to: " + url);
request = new HttpGet(url);
request.addHeader("Accept", "*/*");
if( partialDownloadLen > 0 ) {
request.addHeader("Range", "bytes=" + partialDownloadLen + "-");
Log.i("SDL", "Trying to resume download at pos " + partialDownloadLen);
}
try {
DefaultHttpClient client = HttpWithDisabledSslCertCheck();
client.getParams().setBooleanParameter("http.protocol.handle-redirects", true);
response = client.execute(request);
} catch (IOException e) {
Log.i("SDL", "Failed to connect to " + url);
downloadUrlIndex++;
};
if( response != null )
{
if( response.getStatusLine().getStatusCode() != 200 && response.getStatusLine().getStatusCode() != 206 )
{
Log.i("SDL", "Failed to connect to " + url + " with error " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
responseError = response;
response = null;
downloadUrlIndex++;
}
else
break;
}
}
}
if( FileInAssets )
{
int multipartCounter = 0;
InputStream multipart = null;
while( true )
{
try {
// Make string ".zip000", ".zip001" etc for multipart archives
String url1 = url + String.format("%03d", multipartCounter);
CountingInputStream stream1 = new CountingInputStream(Parent.getAssets().open(url1), 8192);
while( stream1.skip(65536) > 0 ) { };
totalLen += stream1.getBytesRead();
stream1.close();
InputStream s = Parent.getAssets().open(url1);
if( multipart == null )
multipart = s;
else
multipart = new SequenceInputStream(multipart, s);
Log.i("SDL", "Multipart archive found: " + url1);
} catch( IOException e ) {
break;
}
multipartCounter += 1;
}
if( multipart != null )
stream = new CountingInputStream(multipart, 8192);
else
{
try {
stream = new CountingInputStream(Parent.getAssets().open(url), 8192);
while( stream.skip(65536) > 0 ) { };
totalLen += stream.getBytesRead();
stream.close();
stream = new CountingInputStream(Parent.getAssets().open(url), 8192);
} catch( IOException e ) {
Log.i("SDL", "Unpacking from assets '" + url + "' - error: " + e.toString());
Status.setText( res.getString(R.string.error_dl_from, url) );
return false;
}
}
}
else
{
if( response == null )
{
Log.i("SDL", "Error connecting to " + url);
Status.setText( res.getString(R.string.failed_connecting_to, url) + (responseError == null ? "" : ": " + responseError.getStatusLine().getStatusCode() + " " + responseError.getStatusLine().getReasonPhrase()) );
return false;
}
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_from, url) );
totalLen = response.getEntity().getContentLength();
try {
stream = new CountingInputStream(response.getEntity().getContent(), 8192);
} catch( java.io.IOException e ) {
Status.setText( res.getString(R.string.error_dl_from, url) );
return false;
}
}
long updateStatusTime = 0;
if(DoNotUnzip)
{
Log.i("SDL", "Saving file '" + path + "'");
OutputStream out = null;
try {
try {
File outDir = new File( path.substring(0, path.lastIndexOf("/") ));
if( !(outDir.exists() && outDir.isDirectory()) )
outDir.mkdirs();
} catch( SecurityException e ) { };
if( partialDownloadLen > 0 )
{
try {
Header[] range = response.getHeaders("Content-Range");
if( range.length > 0 && range[0].getValue().indexOf("bytes") == 0 )
{
//Log.i("SDL", "Resuming download of file '" + path + "': Content-Range: " + range[0].getValue());
String[] skippedBytes = range[0].getValue().split("/")[0].split("-")[0].split(" ");
if( skippedBytes.length >= 2 && Long.parseLong(skippedBytes[1]) == partialDownloadLen )
{
out = new FileOutputStream( path, true );
Log.i("SDL", "Resuming download of file '" + path + "' at pos " + partialDownloadLen);
}
}
else
Log.i("SDL", "Server does not support partial downloads. " + (range.length == 0 ? "" : range[0].getValue()));
} catch (Exception e) { }
}
if( out == null )
{
out = new FileOutputStream( path );
partialDownloadLen = 0;
}
} catch( FileNotFoundException e ) {
Log.i("SDL", "Saving file '" + path + "' - error creating output file: " + e.toString());
} catch( SecurityException e ) {
Log.i("SDL", "Saving file '" + path + "' - error creating output file: " + e.toString());
};
if( out == null )
{
Status.setText( res.getString(R.string.error_write, path) );
Log.i("SDL", "Saving file '" + path + "' - error creating output file");
return false;
}
try {
int len = stream.read(buf);
while (len >= 0)
{
if(len > 0)
out.write(buf, 0, len);
len = stream.read(buf);
float percent = 0.0f;
if( totalLen > 0 )
percent = (stream.getBytesRead() + partialDownloadLen) * 100.0f / (totalLen + partialDownloadLen);
if( System.currentTimeMillis() > updateStatusTime + 1000 )
{
updateStatusTime = System.currentTimeMillis();
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_progress, percent, path) );
}
}
out.flush();
out.close();
out = null;
} catch( java.io.IOException e ) {
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
Log.i("SDL", "Saving file '" + path + "' - error writing: " + e.toString());
return false;
}
Log.i("SDL", "Saving file '" + path + "' done");
}
else
{
Log.i("SDL", "Reading from zip file '" + url + "'");
ZipInputStream zip = new ZipInputStream(stream);
while(true)
{
ZipEntry entry = null;
try {
entry = zip.getNextEntry();
if( entry != null )
Log.i("SDL", "Reading from zip file '" + url + "' entry '" + entry.getName() + "'");
} catch( java.io.IOException e ) {
Status.setText( res.getString(R.string.error_dl_from, url) );
Log.i("SDL", "Error reading from zip file '" + url + "': " + e.toString());
return false;
}
if( entry == null )
{
Log.i("SDL", "Reading from zip file '" + url + "' finished");
break;
}
if( entry.isDirectory() )
{
Log.i("SDL", "Creating dir '" + getOutFilePath(entry.getName()) + "'");
try {
File outDir = new File( getOutFilePath(entry.getName()) );
if( !(outDir.exists() && outDir.isDirectory()) )
outDir.mkdirs();
} catch( SecurityException e ) { };
continue;
}
OutputStream out = null;
path = getOutFilePath(entry.getName());
float percent = 0.0f;
Log.i("SDL", "Saving file '" + path + "'");
try {
File outDir = new File( path.substring(0, path.lastIndexOf("/") ));
if( !(outDir.exists() && outDir.isDirectory()) )
outDir.mkdirs();
} catch( SecurityException e ) { };
try {
CheckedInputStream check = new CheckedInputStream( new FileInputStream(path), new CRC32() );
while( check.read(buf, 0, buf.length) >= 0 ) {};
check.close();
if( check.getChecksum().getValue() != entry.getCrc() )
{
File ff = new File(path);
ff.delete();
throw new Exception();
}
Log.i("SDL", "File '" + path + "' exists and passed CRC check - not overwriting it");
if( totalLen > 0 )
percent = stream.getBytesRead() * 100.0f / totalLen;
if( System.currentTimeMillis() > updateStatusTime + 1000 )
{
updateStatusTime = System.currentTimeMillis();
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_progress, percent, path) );
}
continue;
} catch( Exception e ) { }
try {
out = new FileOutputStream( path );
} catch( FileNotFoundException e ) {
Log.i("SDL", "Saving file '" + path + "' - cannot create file: " + e.toString());
} catch( SecurityException e ) {
Log.i("SDL", "Saving file '" + path + "' - cannot create file: " + e.toString());
};
if( out == null )
{
Status.setText( res.getString(R.string.error_write, path) );
Log.i("SDL", "Saving file '" + path + "' - cannot create file");
return false;
}
if( totalLen > 0 )
percent = stream.getBytesRead() * 100.0f / totalLen;
if( System.currentTimeMillis() > updateStatusTime + 1000 )
{
updateStatusTime = System.currentTimeMillis();
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_progress, percent, path) );
}
try {
int len = zip.read(buf);
while (len >= 0)
{
if(len > 0)
out.write(buf, 0, len);
len = zip.read(buf);
percent = 0.0f;
if( totalLen > 0 )
percent = stream.getBytesRead() * 100.0f / totalLen;
if( System.currentTimeMillis() > updateStatusTime + 1000 )
{
updateStatusTime = System.currentTimeMillis();
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_progress, percent, path) );
}
}
out.flush();
out.close();
out = null;
} catch( java.io.IOException e ) {
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
Log.i("SDL", "Saving file '" + path + "' - error writing or downloading: " + e.toString());
return false;
}
try {
long count = 0, ret = 0;
CheckedInputStream check = new CheckedInputStream( new FileInputStream(path), new CRC32() );
while( ret >= 0 )
{
count += ret;
ret = check.read(buf, 0, buf.length);
}
check.close();
if( check.getChecksum().getValue() != entry.getCrc() || count != entry.getSize() )
{
File ff = new File(path);
ff.delete();
Log.i("SDL", "Saving file '" + path + "' - CRC check failed, ZIP: " +
String.format("%x", entry.getCrc()) + " actual file: " + String.format("%x", check.getChecksum().getValue()) +
" file size in ZIP: " + entry.getSize() + " actual size " + count );
throw new Exception();
}
} catch( Exception e ) {
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
return false;
}
Log.i("SDL", "Saving file '" + path + "' done");
}
};
OutputStream out = null;
path = getOutFilePath(DownloadFlagFileName);
try {
out = new FileOutputStream( path );
out.write(downloadUrls[downloadUrlIndex].getBytes("UTF-8"));
out.flush();
out.close();
} catch( FileNotFoundException e ) {
} catch( SecurityException e ) {
} catch( java.io.IOException e ) {
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
return false;
};
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_finished) );
try {
stream.close();
} catch( java.io.IOException e ) {
};
return true;
};
private void initParent()
{
class Callback implements Runnable
{
public MainActivity Parent;
public void run()
{
Parent.initSDL();
}
}
Callback cb = new Callback();
synchronized(this) {
cb.Parent = Parent;
if(Parent != null)
Parent.runOnUiThread(cb);
}
}
private String getOutFilePath(final String filename)
{
return outFilesDir + "/" + filename;
};
private static DefaultHttpClient HttpWithDisabledSslCertCheck()
{
return new DefaultHttpClient();
// This code does not work
/*
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient client = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient http = new DefaultHttpClient(mgr, client.getParams());
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
return http;
*/
}
public class BackKeyListener implements MainActivity.KeyEventsListener
{
MainActivity p;
public BackKeyListener(MainActivity _p)
{
p = _p;
}
public void onKeyEvent(final int keyCode)
{
if( DownloadFailed )
System.exit(1);
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.cancel_download));
builder.setMessage(p.getResources().getString(R.string.cancel_download) + (DownloadCanBeResumed ? " " + p.getResources().getString(R.string.cancel_download_resume) : ""));
builder.setPositiveButton(p.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
System.exit(1);
dialog.dismiss();
}
});
builder.setNegativeButton(p.getResources().getString(R.string.no), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
public StatusWriter Status;
public boolean DownloadComplete = false;
public boolean DownloadFailed = false;
public boolean DownloadCanBeResumed = false;
private MainActivity Parent;
private String outFilesDir = null;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,592 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import java.lang.String;
import java.util.ArrayList;
import java.util.Arrays;
import java.lang.reflect.Field;
// Autogenerated by hand with a command:
// grep 'SDLK_' SDL_keysym.h | sed 's/SDLK_\([a-zA-Z0-9_]\+\).*[=] \([0-9]\+\).*/public static final int SDLK_\1 = \2;/' >> Keycodes.java
class SDL_1_2_Keycodes
{
public static final int SDLK_UNKNOWN = 0;
public static final int SDLK_BACKSPACE = 8;
public static final int SDLK_TAB = 9;
public static final int SDLK_CLEAR = 12;
public static final int SDLK_RETURN = 13;
public static final int SDLK_PAUSE = 19;
public static final int SDLK_ESCAPE = 27;
public static final int SDLK_SPACE = 32;
public static final int SDLK_EXCLAIM = 33;
public static final int SDLK_QUOTEDBL = 34;
public static final int SDLK_HASH = 35;
public static final int SDLK_DOLLAR = 36;
public static final int SDLK_AMPERSAND = 38;
public static final int SDLK_QUOTE = 39;
public static final int SDLK_LEFTPAREN = 40;
public static final int SDLK_RIGHTPAREN = 41;
public static final int SDLK_ASTERISK = 42;
public static final int SDLK_PLUS = 43;
public static final int SDLK_COMMA = 44;
public static final int SDLK_MINUS = 45;
public static final int SDLK_PERIOD = 46;
public static final int SDLK_SLASH = 47;
public static final int SDLK_0 = 48;
public static final int SDLK_1 = 49;
public static final int SDLK_2 = 50;
public static final int SDLK_3 = 51;
public static final int SDLK_4 = 52;
public static final int SDLK_5 = 53;
public static final int SDLK_6 = 54;
public static final int SDLK_7 = 55;
public static final int SDLK_8 = 56;
public static final int SDLK_9 = 57;
public static final int SDLK_COLON = 58;
public static final int SDLK_SEMICOLON = 59;
public static final int SDLK_LESS = 60;
public static final int SDLK_EQUALS = 61;
public static final int SDLK_GREATER = 62;
public static final int SDLK_QUESTION = 63;
public static final int SDLK_AT = 64;
public static final int SDLK_LEFTBRACKET = 91;
public static final int SDLK_BACKSLASH = 92;
public static final int SDLK_RIGHTBRACKET = 93;
public static final int SDLK_CARET = 94;
public static final int SDLK_UNDERSCORE = 95;
public static final int SDLK_BACKQUOTE = 96;
public static final int SDLK_a = 97;
public static final int SDLK_b = 98;
public static final int SDLK_c = 99;
public static final int SDLK_d = 100;
public static final int SDLK_e = 101;
public static final int SDLK_f = 102;
public static final int SDLK_g = 103;
public static final int SDLK_h = 104;
public static final int SDLK_i = 105;
public static final int SDLK_j = 106;
public static final int SDLK_k = 107;
public static final int SDLK_l = 108;
public static final int SDLK_m = 109;
public static final int SDLK_n = 110;
public static final int SDLK_o = 111;
public static final int SDLK_p = 112;
public static final int SDLK_q = 113;
public static final int SDLK_r = 114;
public static final int SDLK_s = 115;
public static final int SDLK_t = 116;
public static final int SDLK_u = 117;
public static final int SDLK_v = 118;
public static final int SDLK_w = 119;
public static final int SDLK_x = 120;
public static final int SDLK_y = 121;
public static final int SDLK_z = 122;
public static final int SDLK_DELETE = 127;
public static final int SDLK_WORLD_0 = 160;
public static final int SDLK_WORLD_1 = 161;
public static final int SDLK_WORLD_2 = 162;
public static final int SDLK_WORLD_3 = 163;
public static final int SDLK_WORLD_4 = 164;
public static final int SDLK_WORLD_5 = 165;
public static final int SDLK_WORLD_6 = 166;
public static final int SDLK_WORLD_7 = 167;
public static final int SDLK_WORLD_8 = 168;
public static final int SDLK_WORLD_9 = 169;
public static final int SDLK_WORLD_10 = 170;
public static final int SDLK_WORLD_11 = 171;
public static final int SDLK_WORLD_12 = 172;
public static final int SDLK_WORLD_13 = 173;
public static final int SDLK_WORLD_14 = 174;
public static final int SDLK_WORLD_15 = 175;
public static final int SDLK_WORLD_16 = 176;
public static final int SDLK_WORLD_17 = 177;
public static final int SDLK_WORLD_18 = 178;
public static final int SDLK_WORLD_19 = 179;
public static final int SDLK_WORLD_20 = 180;
public static final int SDLK_WORLD_21 = 181;
public static final int SDLK_WORLD_22 = 182;
public static final int SDLK_WORLD_23 = 183;
public static final int SDLK_WORLD_24 = 184;
public static final int SDLK_WORLD_25 = 185;
public static final int SDLK_WORLD_26 = 186;
public static final int SDLK_WORLD_27 = 187;
public static final int SDLK_WORLD_28 = 188;
public static final int SDLK_WORLD_29 = 189;
public static final int SDLK_WORLD_30 = 190;
public static final int SDLK_WORLD_31 = 191;
public static final int SDLK_WORLD_32 = 192;
public static final int SDLK_WORLD_33 = 193;
public static final int SDLK_WORLD_34 = 194;
public static final int SDLK_WORLD_35 = 195;
public static final int SDLK_WORLD_36 = 196;
public static final int SDLK_WORLD_37 = 197;
public static final int SDLK_WORLD_38 = 198;
public static final int SDLK_WORLD_39 = 199;
public static final int SDLK_WORLD_40 = 200;
public static final int SDLK_WORLD_41 = 201;
public static final int SDLK_WORLD_42 = 202;
public static final int SDLK_WORLD_43 = 203;
public static final int SDLK_WORLD_44 = 204;
public static final int SDLK_WORLD_45 = 205;
public static final int SDLK_WORLD_46 = 206;
public static final int SDLK_WORLD_47 = 207;
public static final int SDLK_WORLD_48 = 208;
public static final int SDLK_WORLD_49 = 209;
public static final int SDLK_WORLD_50 = 210;
public static final int SDLK_WORLD_51 = 211;
public static final int SDLK_WORLD_52 = 212;
public static final int SDLK_WORLD_53 = 213;
public static final int SDLK_WORLD_54 = 214;
public static final int SDLK_WORLD_55 = 215;
public static final int SDLK_WORLD_56 = 216;
public static final int SDLK_WORLD_57 = 217;
public static final int SDLK_WORLD_58 = 218;
public static final int SDLK_WORLD_59 = 219;
public static final int SDLK_WORLD_60 = 220;
public static final int SDLK_WORLD_61 = 221;
public static final int SDLK_WORLD_62 = 222;
public static final int SDLK_WORLD_63 = 223;
public static final int SDLK_WORLD_64 = 224;
public static final int SDLK_WORLD_65 = 225;
public static final int SDLK_WORLD_66 = 226;
public static final int SDLK_WORLD_67 = 227;
public static final int SDLK_WORLD_68 = 228;
public static final int SDLK_WORLD_69 = 229;
public static final int SDLK_WORLD_70 = 230;
public static final int SDLK_WORLD_71 = 231;
public static final int SDLK_WORLD_72 = 232;
public static final int SDLK_WORLD_73 = 233;
public static final int SDLK_WORLD_74 = 234;
public static final int SDLK_WORLD_75 = 235;
public static final int SDLK_WORLD_76 = 236;
public static final int SDLK_WORLD_77 = 237;
public static final int SDLK_WORLD_78 = 238;
public static final int SDLK_WORLD_79 = 239;
public static final int SDLK_WORLD_80 = 240;
public static final int SDLK_WORLD_81 = 241;
public static final int SDLK_WORLD_82 = 242;
public static final int SDLK_WORLD_83 = 243;
public static final int SDLK_WORLD_84 = 244;
public static final int SDLK_WORLD_85 = 245;
public static final int SDLK_WORLD_86 = 246;
public static final int SDLK_WORLD_87 = 247;
public static final int SDLK_WORLD_88 = 248;
public static final int SDLK_WORLD_89 = 249;
public static final int SDLK_WORLD_90 = 250;
public static final int SDLK_WORLD_91 = 251;
public static final int SDLK_WORLD_92 = 252;
public static final int SDLK_WORLD_93 = 253;
public static final int SDLK_WORLD_94 = 254;
public static final int SDLK_WORLD_95 = 255;
public static final int SDLK_KP0 = 256;
public static final int SDLK_KP1 = 257;
public static final int SDLK_KP2 = 258;
public static final int SDLK_KP3 = 259;
public static final int SDLK_KP4 = 260;
public static final int SDLK_KP5 = 261;
public static final int SDLK_KP6 = 262;
public static final int SDLK_KP7 = 263;
public static final int SDLK_KP8 = 264;
public static final int SDLK_KP9 = 265;
public static final int SDLK_KP_PERIOD = 266;
public static final int SDLK_KP_DIVIDE = 267;
public static final int SDLK_KP_MULTIPLY = 268;
public static final int SDLK_KP_MINUS = 269;
public static final int SDLK_KP_PLUS = 270;
public static final int SDLK_KP_ENTER = 271;
public static final int SDLK_KP_EQUALS = 272;
public static final int SDLK_UP = 273;
public static final int SDLK_DOWN = 274;
public static final int SDLK_RIGHT = 275;
public static final int SDLK_LEFT = 276;
public static final int SDLK_INSERT = 277;
public static final int SDLK_HOME = 278;
public static final int SDLK_END = 279;
public static final int SDLK_PAGEUP = 280;
public static final int SDLK_PAGEDOWN = 281;
public static final int SDLK_F1 = 282;
public static final int SDLK_F2 = 283;
public static final int SDLK_F3 = 284;
public static final int SDLK_F4 = 285;
public static final int SDLK_F5 = 286;
public static final int SDLK_F6 = 287;
public static final int SDLK_F7 = 288;
public static final int SDLK_F8 = 289;
public static final int SDLK_F9 = 290;
public static final int SDLK_F10 = 291;
public static final int SDLK_F11 = 292;
public static final int SDLK_F12 = 293;
public static final int SDLK_F13 = 294;
public static final int SDLK_F14 = 295;
public static final int SDLK_F15 = 296;
public static final int SDLK_NUMLOCK = 300;
public static final int SDLK_CAPSLOCK = 301;
public static final int SDLK_SCROLLOCK = 302;
public static final int SDLK_RSHIFT = 303;
public static final int SDLK_LSHIFT = 304;
public static final int SDLK_RCTRL = 305;
public static final int SDLK_LCTRL = 306;
public static final int SDLK_RALT = 307;
public static final int SDLK_LALT = 308;
public static final int SDLK_RMETA = 309;
public static final int SDLK_LMETA = 310;
public static final int SDLK_LSUPER = 311;
public static final int SDLK_RSUPER = 312;
public static final int SDLK_MODE = 313;
public static final int SDLK_COMPOSE = 314;
public static final int SDLK_HELP = 315;
public static final int SDLK_PRINT = 316;
public static final int SDLK_SYSREQ = 317;
public static final int SDLK_BREAK = 318;
public static final int SDLK_MENU = 319;
public static final int SDLK_POWER = 320;
public static final int SDLK_EURO = 321;
public static final int SDLK_UNDO = 322;
public static final int SDLK_NO_REMAP = 512;
}
// Autogenerated by hand with a command:
// grep 'SDL_SCANCODE_' SDL_scancode.h | sed 's/SDL_SCANCODE_\([a-zA-Z0-9_]\+\).*[=] \([0-9]\+\).*/public static final int SDLK_\1 = \2;/' >> Keycodes.java
class SDL_1_3_Keycodes
{
public static final int SDLK_UNKNOWN = 0;
public static final int SDLK_A = 4;
public static final int SDLK_B = 5;
public static final int SDLK_C = 6;
public static final int SDLK_D = 7;
public static final int SDLK_E = 8;
public static final int SDLK_F = 9;
public static final int SDLK_G = 10;
public static final int SDLK_H = 11;
public static final int SDLK_I = 12;
public static final int SDLK_J = 13;
public static final int SDLK_K = 14;
public static final int SDLK_L = 15;
public static final int SDLK_M = 16;
public static final int SDLK_N = 17;
public static final int SDLK_O = 18;
public static final int SDLK_P = 19;
public static final int SDLK_Q = 20;
public static final int SDLK_R = 21;
public static final int SDLK_S = 22;
public static final int SDLK_T = 23;
public static final int SDLK_U = 24;
public static final int SDLK_V = 25;
public static final int SDLK_W = 26;
public static final int SDLK_X = 27;
public static final int SDLK_Y = 28;
public static final int SDLK_Z = 29;
public static final int SDLK_1 = 30;
public static final int SDLK_2 = 31;
public static final int SDLK_3 = 32;
public static final int SDLK_4 = 33;
public static final int SDLK_5 = 34;
public static final int SDLK_6 = 35;
public static final int SDLK_7 = 36;
public static final int SDLK_8 = 37;
public static final int SDLK_9 = 38;
public static final int SDLK_0 = 39;
public static final int SDLK_RETURN = 40;
public static final int SDLK_ESCAPE = 41;
public static final int SDLK_BACKSPACE = 42;
public static final int SDLK_TAB = 43;
public static final int SDLK_SPACE = 44;
public static final int SDLK_MINUS = 45;
public static final int SDLK_EQUALS = 46;
public static final int SDLK_LEFTBRACKET = 47;
public static final int SDLK_RIGHTBRACKET = 48;
public static final int SDLK_BACKSLASH = 49;
public static final int SDLK_NONUSHASH = 50;
public static final int SDLK_SEMICOLON = 51;
public static final int SDLK_APOSTROPHE = 52;
public static final int SDLK_GRAVE = 53;
public static final int SDLK_COMMA = 54;
public static final int SDLK_PERIOD = 55;
public static final int SDLK_SLASH = 56;
public static final int SDLK_CAPSLOCK = 57;
public static final int SDLK_F1 = 58;
public static final int SDLK_F2 = 59;
public static final int SDLK_F3 = 60;
public static final int SDLK_F4 = 61;
public static final int SDLK_F5 = 62;
public static final int SDLK_F6 = 63;
public static final int SDLK_F7 = 64;
public static final int SDLK_F8 = 65;
public static final int SDLK_F9 = 66;
public static final int SDLK_F10 = 67;
public static final int SDLK_F11 = 68;
public static final int SDLK_F12 = 69;
public static final int SDLK_PRINTSCREEN = 70;
public static final int SDLK_SCROLLLOCK = 71;
public static final int SDLK_PAUSE = 72;
public static final int SDLK_INSERT = 73;
public static final int SDLK_HOME = 74;
public static final int SDLK_PAGEUP = 75;
public static final int SDLK_DELETE = 76;
public static final int SDLK_END = 77;
public static final int SDLK_PAGEDOWN = 78;
public static final int SDLK_RIGHT = 79;
public static final int SDLK_LEFT = 80;
public static final int SDLK_DOWN = 81;
public static final int SDLK_UP = 82;
public static final int SDLK_NUMLOCKCLEAR = 83;
public static final int SDLK_KP_DIVIDE = 84;
public static final int SDLK_KP_MULTIPLY = 85;
public static final int SDLK_KP_MINUS = 86;
public static final int SDLK_KP_PLUS = 87;
public static final int SDLK_KP_ENTER = 88;
public static final int SDLK_KP_1 = 89;
public static final int SDLK_KP_2 = 90;
public static final int SDLK_KP_3 = 91;
public static final int SDLK_KP_4 = 92;
public static final int SDLK_KP_5 = 93;
public static final int SDLK_KP_6 = 94;
public static final int SDLK_KP_7 = 95;
public static final int SDLK_KP_8 = 96;
public static final int SDLK_KP_9 = 97;
public static final int SDLK_KP_0 = 98;
public static final int SDLK_KP_PERIOD = 99;
public static final int SDLK_NONUSBACKSLASH = 100;
public static final int SDLK_APPLICATION = 101;
public static final int SDLK_POWER = 102;
public static final int SDLK_KP_EQUALS = 103;
public static final int SDLK_F13 = 104;
public static final int SDLK_F14 = 105;
public static final int SDLK_F15 = 106;
public static final int SDLK_F16 = 107;
public static final int SDLK_F17 = 108;
public static final int SDLK_F18 = 109;
public static final int SDLK_F19 = 110;
public static final int SDLK_F20 = 111;
public static final int SDLK_F21 = 112;
public static final int SDLK_F22 = 113;
public static final int SDLK_F23 = 114;
public static final int SDLK_F24 = 115;
public static final int SDLK_EXECUTE = 116;
public static final int SDLK_HELP = 117;
public static final int SDLK_MENU = 118;
public static final int SDLK_SELECT = 119;
public static final int SDLK_STOP = 120;
public static final int SDLK_AGAIN = 121;
public static final int SDLK_UNDO = 122;
public static final int SDLK_CUT = 123;
public static final int SDLK_COPY = 124;
public static final int SDLK_PASTE = 125;
public static final int SDLK_FIND = 126;
public static final int SDLK_MUTE = 127;
public static final int SDLK_VOLUMEUP = 128;
public static final int SDLK_VOLUMEDOWN = 129;
public static final int SDLK_KP_COMMA = 133;
public static final int SDLK_KP_EQUALSAS400 = 134;
public static final int SDLK_INTERNATIONAL1 = 135;
public static final int SDLK_INTERNATIONAL2 = 136;
public static final int SDLK_INTERNATIONAL3 = 137;
public static final int SDLK_INTERNATIONAL4 = 138;
public static final int SDLK_INTERNATIONAL5 = 139;
public static final int SDLK_INTERNATIONAL6 = 140;
public static final int SDLK_INTERNATIONAL7 = 141;
public static final int SDLK_INTERNATIONAL8 = 142;
public static final int SDLK_INTERNATIONAL9 = 143;
public static final int SDLK_LANG1 = 144;
public static final int SDLK_LANG2 = 145;
public static final int SDLK_LANG3 = 146;
public static final int SDLK_LANG4 = 147;
public static final int SDLK_LANG5 = 148;
public static final int SDLK_LANG6 = 149;
public static final int SDLK_LANG7 = 150;
public static final int SDLK_LANG8 = 151;
public static final int SDLK_LANG9 = 152;
public static final int SDLK_ALTERASE = 153;
public static final int SDLK_SYSREQ = 154;
public static final int SDLK_CANCEL = 155;
public static final int SDLK_CLEAR = 156;
public static final int SDLK_PRIOR = 157;
public static final int SDLK_RETURN2 = 158;
public static final int SDLK_SEPARATOR = 159;
public static final int SDLK_OUT = 160;
public static final int SDLK_OPER = 161;
public static final int SDLK_CLEARAGAIN = 162;
public static final int SDLK_CRSEL = 163;
public static final int SDLK_EXSEL = 164;
public static final int SDLK_KP_00 = 176;
public static final int SDLK_KP_000 = 177;
public static final int SDLK_THOUSANDSSEPARATOR = 178;
public static final int SDLK_DECIMALSEPARATOR = 179;
public static final int SDLK_CURRENCYUNIT = 180;
public static final int SDLK_CURRENCYSUBUNIT = 181;
public static final int SDLK_KP_LEFTPAREN = 182;
public static final int SDLK_KP_RIGHTPAREN = 183;
public static final int SDLK_KP_LEFTBRACE = 184;
public static final int SDLK_KP_RIGHTBRACE = 185;
public static final int SDLK_KP_TAB = 186;
public static final int SDLK_KP_BACKSPACE = 187;
public static final int SDLK_KP_A = 188;
public static final int SDLK_KP_B = 189;
public static final int SDLK_KP_C = 190;
public static final int SDLK_KP_D = 191;
public static final int SDLK_KP_E = 192;
public static final int SDLK_KP_F = 193;
public static final int SDLK_KP_XOR = 194;
public static final int SDLK_KP_POWER = 195;
public static final int SDLK_KP_PERCENT = 196;
public static final int SDLK_KP_LESS = 197;
public static final int SDLK_KP_GREATER = 198;
public static final int SDLK_KP_AMPERSAND = 199;
public static final int SDLK_KP_DBLAMPERSAND = 200;
public static final int SDLK_KP_VERTICALBAR = 201;
public static final int SDLK_KP_DBLVERTICALBAR = 202;
public static final int SDLK_KP_COLON = 203;
public static final int SDLK_KP_HASH = 204;
public static final int SDLK_KP_SPACE = 205;
public static final int SDLK_KP_AT = 206;
public static final int SDLK_KP_EXCLAM = 207;
public static final int SDLK_KP_MEMSTORE = 208;
public static final int SDLK_KP_MEMRECALL = 209;
public static final int SDLK_KP_MEMCLEAR = 210;
public static final int SDLK_KP_MEMADD = 211;
public static final int SDLK_KP_MEMSUBTRACT = 212;
public static final int SDLK_KP_MEMMULTIPLY = 213;
public static final int SDLK_KP_MEMDIVIDE = 214;
public static final int SDLK_KP_PLUSMINUS = 215;
public static final int SDLK_KP_CLEAR = 216;
public static final int SDLK_KP_CLEARENTRY = 217;
public static final int SDLK_KP_BINARY = 218;
public static final int SDLK_KP_OCTAL = 219;
public static final int SDLK_KP_DECIMAL = 220;
public static final int SDLK_KP_HEXADECIMAL = 221;
public static final int SDLK_LCTRL = 224;
public static final int SDLK_LSHIFT = 225;
public static final int SDLK_LALT = 226;
public static final int SDLK_LGUI = 227;
public static final int SDLK_RCTRL = 228;
public static final int SDLK_RSHIFT = 229;
public static final int SDLK_RALT = 230;
public static final int SDLK_RGUI = 231;
public static final int SDLK_MODE = 257;
public static final int SDLK_AUDIONEXT = 258;
public static final int SDLK_AUDIOPREV = 259;
public static final int SDLK_AUDIOSTOP = 260;
public static final int SDLK_AUDIOPLAY = 261;
public static final int SDLK_AUDIOMUTE = 262;
public static final int SDLK_MEDIASELECT = 263;
public static final int SDLK_WWW = 264;
public static final int SDLK_MAIL = 265;
public static final int SDLK_CALCULATOR = 266;
public static final int SDLK_COMPUTER = 267;
public static final int SDLK_AC_SEARCH = 268;
public static final int SDLK_AC_HOME = 269;
public static final int SDLK_AC_BACK = 270;
public static final int SDLK_AC_FORWARD = 271;
public static final int SDLK_AC_STOP = 272;
public static final int SDLK_AC_REFRESH = 273;
public static final int SDLK_AC_BOOKMARKS = 274;
public static final int SDLK_BRIGHTNESSDOWN = 275;
public static final int SDLK_BRIGHTNESSUP = 276;
public static final int SDLK_DISPLAYSWITCH = 277;
public static final int SDLK_KBDILLUMTOGGLE = 278;
public static final int SDLK_KBDILLUMDOWN = 279;
public static final int SDLK_KBDILLUMUP = 280;
public static final int SDLK_EJECT = 281;
public static final int SDLK_SLEEP = 282;
public static final int SDLK_NO_REMAP = 512;
}
class SDL_Keys
{
public static String [] names = null;
public static Integer [] values = null;
public static String [] namesSorted = null;
public static Integer [] namesSortedIdx = null;
public static Integer [] namesSortedBackIdx = null;
static final int JAVA_KEYCODE_LAST = 255; // Android 2.3 added several new gaming keys, Android 3.1 added even more - keep in sync with javakeycodes.h
static String getName(int v)
{
for( int f = 0; f < values.length; f++ )
{
if( values[f] == v )
return names[f];
}
return names[0];
}
static
{
ArrayList<String> Names = new ArrayList<String> ();
ArrayList<Integer> Values = new ArrayList<Integer> ();
Field [] fields = SDL_1_2_Keycodes.class.getDeclaredFields();
if( Globals.Using_SDL_1_3 )
{
fields = SDL_1_3_Keycodes.class.getDeclaredFields();
}
try {
for(Field f: fields)
{
Values.add(f.getInt(null));
Names.add(f.getName().substring(5).toUpperCase());
}
} catch(IllegalAccessException e) {};
// Sort by value
for( int i = 0; i < Values.size(); i++ )
{
for( int j = i; j < Values.size(); j++ )
{
if( Values.get(i) > Values.get(j) )
{
int x = Values.get(i);
Values.set(i, Values.get(j));
Values.set(j, x);
String s = Names.get(i);
Names.set(i, Names.get(j));
Names.set(j, s);
}
}
}
names = Names.toArray(new String[0]);
values = Values.toArray(new Integer[0]);
namesSorted = Names.toArray(new String[0]);
namesSortedIdx = new Integer[values.length];
namesSortedBackIdx = new Integer[values.length];
Arrays.sort(namesSorted);
for( int i = 0; i < namesSorted.length; i++ )
{
for( int j = 0; j < namesSorted.length; j++ )
{
if( namesSorted[i].equals( names[j] ) )
{
namesSortedIdx[i] = j;
namesSortedBackIdx[j] = i;
break;
}
}
}
}
}

View File

@@ -0,0 +1,782 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.Log;
import java.io.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.StatFs;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.lang.String;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.FrameLayout;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Button;
import android.view.View;
import android.widget.LinearLayout;
import android.text.Editable;
import android.text.SpannedString;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.widget.Toast;
// TODO: too much code here, split into multiple files, possibly auto-generated menus?
class Settings
{
static String SettingsFileName = "libsdl-settings.cfg";
static boolean settingsLoaded = false;
static boolean settingsChanged = false;
static final int SETTINGS_FILE_VERSION = 5;
static void Save(final MainActivity p)
{
try {
ObjectOutputStream out = new ObjectOutputStream(p.openFileOutput( SettingsFileName, p.MODE_WORLD_READABLE ));
out.writeInt(SETTINGS_FILE_VERSION);
out.writeBoolean(Globals.DownloadToSdcard);
out.writeBoolean(Globals.PhoneHasArrowKeys);
out.writeBoolean(Globals.PhoneHasTrackball);
out.writeBoolean(Globals.UseAccelerometerAsArrowKeys);
out.writeBoolean(Globals.UseTouchscreenKeyboard);
out.writeInt(Globals.TouchscreenKeyboardSize);
out.writeInt(Globals.AccelerometerSensitivity);
out.writeInt(Globals.AccelerometerCenterPos);
out.writeInt(Globals.TrackballDampening);
out.writeInt(Globals.AudioBufferConfig);
out.writeInt(Globals.TouchscreenKeyboardTheme);
out.writeInt(Globals.RightClickMethod);
out.writeInt(Globals.ShowScreenUnderFinger);
out.writeInt(Globals.LeftClickMethod);
out.writeBoolean(Globals.MoveMouseWithJoystick);
out.writeBoolean(Globals.ClickMouseWithDpad);
out.writeInt(Globals.ClickScreenPressure);
out.writeInt(Globals.ClickScreenTouchspotSize);
out.writeBoolean(Globals.KeepAspectRatio);
out.writeInt(Globals.MoveMouseWithJoystickSpeed);
out.writeInt(Globals.MoveMouseWithJoystickAccel);
out.writeInt(SDL_Keys.JAVA_KEYCODE_LAST);
for( int i = 0; i < SDL_Keys.JAVA_KEYCODE_LAST; i++ )
{
out.writeInt(Globals.RemapHwKeycode[i]);
}
out.writeInt(Globals.RemapScreenKbKeycode.length);
for( int i = 0; i < Globals.RemapScreenKbKeycode.length; i++ )
{
out.writeInt(Globals.RemapScreenKbKeycode[i]);
}
out.writeInt(Globals.ScreenKbControlsShown.length);
for( int i = 0; i < Globals.ScreenKbControlsShown.length; i++ )
{
out.writeBoolean(Globals.ScreenKbControlsShown[i]);
}
out.writeInt(Globals.TouchscreenKeyboardTransparency);
out.writeInt(Globals.RemapMultitouchGestureKeycode.length);
for( int i = 0; i < Globals.RemapMultitouchGestureKeycode.length; i++ )
{
out.writeInt(Globals.RemapMultitouchGestureKeycode[i]);
out.writeBoolean(Globals.MultitouchGesturesUsed[i]);
}
out.writeInt(Globals.MultitouchGestureSensitivity);
for( int i = 0; i < Globals.TouchscreenCalibration.length; i++ )
out.writeInt(Globals.TouchscreenCalibration[i]);
out.writeInt(Globals.DataDir.length());
for( int i = 0; i < Globals.DataDir.length(); i++ )
out.writeChar(Globals.DataDir.charAt(i));
out.writeInt(Globals.CommandLine.length());
for( int i = 0; i < Globals.CommandLine.length(); i++ )
out.writeChar(Globals.CommandLine.charAt(i));
out.writeInt(Globals.ScreenKbControlsLayout.length);
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
for( int ii = 0; ii < 4; ii++ )
out.writeInt(Globals.ScreenKbControlsLayout[i][ii]);
out.writeInt(Globals.LeftClickKey);
out.writeInt(Globals.RightClickKey);
out.writeBoolean(Globals.VideoLinearFilter);
out.writeInt(Globals.LeftClickTimeout);
out.writeInt(Globals.RightClickTimeout);
out.writeBoolean(Globals.RelativeMouseMovement);
out.writeInt(Globals.RelativeMouseMovementSpeed);
out.writeInt(Globals.RelativeMouseMovementAccel);
out.writeBoolean(Globals.MultiThreadedVideo);
out.writeInt(Globals.OptionalDataDownload.length);
for(int i = 0; i < Globals.OptionalDataDownload.length; i++)
out.writeBoolean(Globals.OptionalDataDownload[i]);
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.writeBoolean(Globals.OuyaEmulation);
out.close();
settingsLoaded = true;
} catch( FileNotFoundException e ) {
} catch( SecurityException e ) {
} catch ( IOException e ) {};
}
static void Load( final MainActivity p )
{
if(settingsLoaded) // Prevent starting twice
{
return;
}
Log.i("SDL", "libSDL: Settings.Load(): enter");
/*nativeInitKeymap(); // TODO: Disabled in SDL2
if( p.isRunningOnOUYA() )
nativeSetKeymapKey(KeyEvent.KEYCODE_MENU, nativeGetKeymapKey(KeyEvent.KEYCODE_BACK)); // Ouya does not have Back key, only Menu, so remap Back keycode to Menu
for( int i = 0; i < SDL_Keys.JAVA_KEYCODE_LAST; i++ )
{
int sdlKey = nativeGetKeymapKey(i);
int idx = 0;
for(int ii = 0; ii < SDL_Keys.values.length; ii++)
if(SDL_Keys.values[ii] == sdlKey)
idx = ii;
Globals.RemapHwKeycode[i] = idx;
}
for( int i = 0; i < Globals.RemapScreenKbKeycode.length; i++ )
{
int sdlKey = nativeGetKeymapKeyScreenKb(i);
int idx = 0;
for(int ii = 0; ii < SDL_Keys.values.length; ii++)
if(SDL_Keys.values[ii] == sdlKey)
idx = ii;
Globals.RemapScreenKbKeycode[i] = idx;
}*/
Globals.ScreenKbControlsShown[0] = (Globals.AppNeedsArrowKeys || Globals.AppUsesJoystick);
Globals.ScreenKbControlsShown[1] = Globals.AppNeedsTextInput;
for( int i = 2; i < Globals.ScreenKbControlsShown.length; i++ )
Globals.ScreenKbControlsShown[i] = ( i - 2 < Globals.AppTouchscreenKeyboardKeysAmount );
if( Globals.AppUsesSecondJoystick )
Globals.ScreenKbControlsShown[8] = true;
/*for( int i = 0; i < Globals.RemapMultitouchGestureKeycode.length; i++ )
{
int sdlKey = nativeGetKeymapKeyMultitouchGesture(i);
int idx = 0;
for(int ii = 0; ii < SDL_Keys.values.length; ii++)
if(SDL_Keys.values[ii] == sdlKey)
idx = ii;
Globals.RemapMultitouchGestureKeycode[i] = idx;
}*/
for( int i = 0; i < Globals.MultitouchGesturesUsed.length; i++ )
Globals.MultitouchGesturesUsed[i] = true;
// Adjust coordinates of on-screen buttons from 800x480
int displayX = 800;
int displayY = 480;
try {
DisplayMetrics dm = new DisplayMetrics();
p.getWindowManager().getDefaultDisplay().getMetrics(dm);
displayX = dm.widthPixels;
displayY = dm.heightPixels;
} catch (Exception eeeee) {}
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
{
Globals.ScreenKbControlsLayout[i][0] *= (float)displayX / 800.0f;
Globals.ScreenKbControlsLayout[i][2] *= (float)displayX / 800.0f;
Globals.ScreenKbControlsLayout[i][1] *= (float)displayY / 480.0f;
Globals.ScreenKbControlsLayout[i][3] *= (float)displayY / 480.0f;
// Make them square
int wh = Math.min( Globals.ScreenKbControlsLayout[i][2] - Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][3] - Globals.ScreenKbControlsLayout[i][1] );
Globals.ScreenKbControlsLayout[i][2] = Globals.ScreenKbControlsLayout[i][0] + wh;
Globals.ScreenKbControlsLayout[i][3] = Globals.ScreenKbControlsLayout[i][1] + wh;
}
Log.i("SDL", "android.os.Build.MODEL: " + android.os.Build.MODEL);
if( (android.os.Build.MODEL.equals("GT-N7000") || android.os.Build.MODEL.equals("SGH-I717"))
&& android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.GINGERBREAD_MR1 )
{
// Samsung Galaxy Note generates a keypress when you hover a stylus over the screen, and that messes up OpenTTD dialogs
// ICS update sends events in a proper way
Globals.RemapHwKeycode[112] = SDL_1_2_Keycodes.SDLK_UNKNOWN;
}
try {
ObjectInputStream settingsFile = new ObjectInputStream(new FileInputStream( p.getFilesDir().getAbsolutePath() + "/" + SettingsFileName ));
if( settingsFile.readInt() != SETTINGS_FILE_VERSION )
throw new IOException();
Globals.DownloadToSdcard = settingsFile.readBoolean();
Globals.PhoneHasArrowKeys = settingsFile.readBoolean();
Globals.PhoneHasTrackball = settingsFile.readBoolean();
Globals.UseAccelerometerAsArrowKeys = settingsFile.readBoolean();
Globals.UseTouchscreenKeyboard = settingsFile.readBoolean();
Globals.TouchscreenKeyboardSize = settingsFile.readInt();
Globals.AccelerometerSensitivity = settingsFile.readInt();
Globals.AccelerometerCenterPos = settingsFile.readInt();
Globals.TrackballDampening = settingsFile.readInt();
Globals.AudioBufferConfig = settingsFile.readInt();
Globals.TouchscreenKeyboardTheme = settingsFile.readInt();
Globals.RightClickMethod = settingsFile.readInt();
Globals.ShowScreenUnderFinger = settingsFile.readInt();
Globals.LeftClickMethod = settingsFile.readInt();
Globals.MoveMouseWithJoystick = settingsFile.readBoolean();
Globals.ClickMouseWithDpad = settingsFile.readBoolean();
Globals.ClickScreenPressure = settingsFile.readInt();
Globals.ClickScreenTouchspotSize = settingsFile.readInt();
Globals.KeepAspectRatio = settingsFile.readBoolean();
Globals.MoveMouseWithJoystickSpeed = settingsFile.readInt();
Globals.MoveMouseWithJoystickAccel = settingsFile.readInt();
int readKeys = settingsFile.readInt();
for( int i = 0; i < readKeys; i++ )
{
Globals.RemapHwKeycode[i] = settingsFile.readInt();
}
if( settingsFile.readInt() != Globals.RemapScreenKbKeycode.length )
throw new IOException();
for( int i = 0; i < Globals.RemapScreenKbKeycode.length; i++ )
{
Globals.RemapScreenKbKeycode[i] = settingsFile.readInt();
}
if( settingsFile.readInt() != Globals.ScreenKbControlsShown.length )
throw new IOException();
for( int i = 0; i < Globals.ScreenKbControlsShown.length; i++ )
{
Globals.ScreenKbControlsShown[i] = settingsFile.readBoolean();
}
Globals.TouchscreenKeyboardTransparency = settingsFile.readInt();
if( settingsFile.readInt() != Globals.RemapMultitouchGestureKeycode.length )
throw new IOException();
for( int i = 0; i < Globals.RemapMultitouchGestureKeycode.length; i++ )
{
Globals.RemapMultitouchGestureKeycode[i] = settingsFile.readInt();
Globals.MultitouchGesturesUsed[i] = settingsFile.readBoolean();
}
Globals.MultitouchGestureSensitivity = settingsFile.readInt();
for( int i = 0; i < Globals.TouchscreenCalibration.length; i++ )
Globals.TouchscreenCalibration[i] = settingsFile.readInt();
StringBuilder b = new StringBuilder();
int len = settingsFile.readInt();
for( int i = 0; i < len; i++ )
b.append( settingsFile.readChar() );
Globals.DataDir = b.toString();
b = new StringBuilder();
len = settingsFile.readInt();
for( int i = 0; i < len; i++ )
b.append( settingsFile.readChar() );
Globals.CommandLine = b.toString();
if( settingsFile.readInt() != Globals.ScreenKbControlsLayout.length )
throw new IOException();
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
for( int ii = 0; ii < 4; ii++ )
Globals.ScreenKbControlsLayout[i][ii] = settingsFile.readInt();
Globals.LeftClickKey = settingsFile.readInt();
Globals.RightClickKey = settingsFile.readInt();
Globals.VideoLinearFilter = settingsFile.readBoolean();
Globals.LeftClickTimeout = settingsFile.readInt();
Globals.RightClickTimeout = settingsFile.readInt();
Globals.RelativeMouseMovement = settingsFile.readBoolean();
Globals.RelativeMouseMovementSpeed = settingsFile.readInt();
Globals.RelativeMouseMovementAccel = settingsFile.readInt();
Globals.MultiThreadedVideo = settingsFile.readBoolean();
Globals.OptionalDataDownload = new boolean[settingsFile.readInt()];
for(int i = 0; i < Globals.OptionalDataDownload.length; i++)
Globals.OptionalDataDownload[i] = settingsFile.readBoolean();
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();
Globals.OuyaEmulation = settingsFile.readBoolean();
settingsLoaded = true;
Log.i("SDL", "libSDL: Settings.Load(): loaded settings successfully");
settingsFile.close();
Log.i("SDL", "libSDL: old cfg version " + cfgVersion + ", our version " + p.getApplicationVersion());
if( cfgVersion != p.getApplicationVersion() )
{
DeleteFilesOnUpgrade(p);
if( Globals.ResetSdlConfigForThisVersion )
{
Log.i("SDL", "libSDL: old cfg version " + cfgVersion + ", our version " + p.getApplicationVersion() + " and we need to clean up config file");
// Delete settings file, and restart the application
DeleteSdlConfigOnUpgradeAndRestart(p);
}
Save(p);
}
return;
} catch( FileNotFoundException e ) {
} catch( SecurityException e ) {
} catch ( IOException e ) {
DeleteFilesOnUpgrade(p);
if( Globals.ResetSdlConfigForThisVersion )
{
Log.i("SDL", "libSDL: old cfg version unknown or too old, our version " + p.getApplicationVersion() + " and we need to clean up config file");
DeleteSdlConfigOnUpgradeAndRestart(p);
}
};
if( Globals.DataDir.length() == 0 )
{
if( !Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) )
{
Log.i("SDL", "libSDL: SD card or external storage is not mounted (state " + Environment.getExternalStorageState() + "), switching to the internal storage.");
Globals.DownloadToSdcard = false;
}
Globals.DataDir = Globals.DownloadToSdcard ?
SdcardAppPath.getPath(p) :
p.getFilesDir().getAbsolutePath();
if( Globals.DownloadToSdcard )
{
// Check if data already installed into deprecated location at /sdcard/app-data/<package-name>
String[] fileList = new File(SdcardAppPath.deprecatedPath(p)).list();
if( fileList != null )
for( String s: fileList )
if( s.toUpperCase().startsWith(DataDownloader.DOWNLOAD_FLAG_FILENAME.toUpperCase()) )
Globals.DataDir = SdcardAppPath.deprecatedPath(p);
}
}
Log.i("SDL", "libSDL: Settings.Load(): loading settings failed, running config dialog");
p.setUpStatusLabel();
if( checkRamSize(p) )
SettingsMenu.showConfig(p, true);
}
// ===============================================================================================
public static boolean deleteRecursively(File dir)
{
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++)
{
boolean success = deleteRecursively(new File(dir, children[i]));
if (!success)
return false;
}
}
return dir.delete();
}
public static boolean deleteRecursivelyAndLog(File dir)
{
Log.v("SDL", "Deleting old file: " + dir.getAbsolutePath() + " exists " + dir.exists());
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++)
{
boolean success = deleteRecursively(new File(dir, children[i]));
if (!success)
return false;
}
}
return dir.delete();
}
public static void DeleteFilesOnUpgrade(final MainActivity p)
{
String [] files = Globals.DeleteFilesOnUpgrade.split(" ");
for(String path: files)
{
if( path.equals("") )
continue;
deleteRecursivelyAndLog(new File( SdcardAppPath.getPath(p) + "/" + path ));
deleteRecursivelyAndLog(new File( p.getFilesDir().getAbsolutePath() + "/" + path ));
deleteRecursivelyAndLog(new File( SdcardAppPath.deprecatedPath(p) + "/" + path ));
}
}
public static void DeleteSdlConfigOnUpgradeAndRestart(final MainActivity p)
{
try {
ObjectOutputStream out = new ObjectOutputStream(p.openFileOutput( SettingsFileName, p.MODE_WORLD_READABLE ));
out.writeInt(-1);
out.close();
} catch( FileNotFoundException e ) {
} catch ( IOException e ) { }
new File( p.getFilesDir() + "/" + SettingsFileName ).delete();
PendingIntent intent = PendingIntent.getActivity(p, 0, new Intent(p.getIntent()), p.getIntent().getFlags());
AlarmManager mgr = (AlarmManager) p.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, intent);
System.exit(0);
}
// ===============================================================================================
static void Apply(MainActivity p)
{
nativeSetVideoDepth(Globals.VideoDepthBpp, Globals.NeedGles2 ? 1 : 0);
if(Globals.VideoLinearFilter)
nativeSetVideoLinearFilter();
if( Globals.CompatibilityHacksVideo )
{
Globals.MultiThreadedVideo = true;
Globals.SwVideoMode = true;
nativeSetCompatibilityHacks();
}
if( Globals.SwVideoMode )
nativeSetVideoForceSoftwareMode();
if( Globals.SwVideoMode && Globals.MultiThreadedVideo )
nativeSetVideoMultithreaded();
if( Globals.PhoneHasTrackball )
nativeSetTrackballUsed();
if( Globals.AppUsesMouse )
nativeSetMouseUsed( Globals.RightClickMethod,
Globals.ShowScreenUnderFinger,
Globals.LeftClickMethod,
Globals.MoveMouseWithJoystick ? 1 : 0,
Globals.ClickMouseWithDpad ? 1 : 0,
Globals.ClickScreenPressure,
Globals.ClickScreenTouchspotSize,
Globals.MoveMouseWithJoystickSpeed,
Globals.MoveMouseWithJoystickAccel,
Globals.LeftClickKey,
Globals.RightClickKey,
Globals.LeftClickTimeout,
Globals.RightClickTimeout,
Globals.RelativeMouseMovement ? 1 : 0,
Globals.RelativeMouseMovementSpeed,
Globals.RelativeMouseMovementAccel,
Globals.ShowMouseCursor ? 1 : 0 );
nativeSetJoystickUsed(Globals.AppUsesJoystick ? 1 : 0, Globals.AppUsesSecondJoystick ? 1 : 0);
if( Globals.AppUsesAccelerometer )
nativeSetAccelerometerUsed();
if( Globals.AppUsesMultitouch )
nativeSetMultitouchUsed();
nativeSetAccelerometerSettings(Globals.AccelerometerSensitivity, Globals.AccelerometerCenterPos);
nativeSetTrackballDampening(Globals.TrackballDampening);
if( Globals.UseTouchscreenKeyboard )
{
boolean screenKbReallyUsed = false;
for( int i = 0; i < Globals.ScreenKbControlsShown.length; i++ )
if( Globals.ScreenKbControlsShown[i] )
screenKbReallyUsed = true;
if( p.isRunningOnOUYA() )
screenKbReallyUsed = false;
if( screenKbReallyUsed )
{
nativeSetTouchscreenKeyboardUsed();
nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize,
Globals.TouchscreenKeyboardDrawSize,
Globals.TouchscreenKeyboardTheme,
Globals.AppTouchscreenKeyboardKeysAmountAutoFire,
Globals.TouchscreenKeyboardTransparency );
SetupTouchscreenKeyboardGraphics(p);
for( int i = 0; i < Globals.RemapScreenKbKeycode.length; i++ )
nativeSetKeymapKeyScreenKb(i, SDL_Keys.values[Globals.RemapScreenKbKeycode[i]]);
if( Globals.TouchscreenKeyboardSize == Globals.TOUCHSCREEN_KEYBOARD_CUSTOM )
{
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
if( Globals.ScreenKbControlsLayout[i][0] < Globals.ScreenKbControlsLayout[i][2] )
nativeSetScreenKbKeyLayout( i, Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][1],
Globals.ScreenKbControlsLayout[i][2], Globals.ScreenKbControlsLayout[i][3]);
}
for( int i = 0; i < Globals.ScreenKbControlsShown.length; i++ )
nativeSetScreenKbKeyUsed(i, Globals.ScreenKbControlsShown[i] ? 1 : 0);
}
else
Globals.UseTouchscreenKeyboard = false;
}
for( int i = 0; i < SDL_Keys.JAVA_KEYCODE_LAST; i++ )
nativeSetKeymapKey(i, SDL_Keys.values[Globals.RemapHwKeycode[i]]);
for( int i = 0; i < Globals.RemapMultitouchGestureKeycode.length; i++ )
nativeSetKeymapKeyMultitouchGesture(i, Globals.MultitouchGesturesUsed[i] ? SDL_Keys.values[Globals.RemapMultitouchGestureKeycode[i]] : 0);
nativeSetMultitouchGestureSensitivity(Globals.MultitouchGestureSensitivity);
if( Globals.TouchscreenCalibration[2] > Globals.TouchscreenCalibration[0] )
nativeSetTouchscreenCalibration(Globals.TouchscreenCalibration[0], Globals.TouchscreenCalibration[1],
Globals.TouchscreenCalibration[2], Globals.TouchscreenCalibration[3]);
String lang = new String(Locale.getDefault().getLanguage());
if( Locale.getDefault().getCountry().length() > 0 )
lang = lang + "_" + Locale.getDefault().getCountry();
Log.i("SDL", "libSDL: setting envvar LANGUAGE to '" + lang + "'");
nativeSetEnv( "LANG", lang );
nativeSetEnv( "LANGUAGE", lang );
// TODO: get current user name and set envvar USER, the API is not availalbe on Android 1.6 so I don't bother with this
nativeSetEnv( "APPDIR", p.getFilesDir().getAbsolutePath() );
nativeSetEnv( "SECURE_STORAGE_DIR", p.getFilesDir().getAbsolutePath() );
nativeSetEnv( "DATADIR", Globals.DataDir );
nativeSetEnv( "UNSECURE_STORAGE_DIR", Globals.DataDir );
nativeSetEnv( "HOME", Globals.DataDir );
nativeSetEnv( "ANDROID_VERSION", String.valueOf(android.os.Build.VERSION.SDK_INT) );
Log.d("SDL", "libSDL: Is running on OUYA: " + p.isRunningOnOUYA());
if( p.isRunningOnOUYA() )
nativeSetEnv( "OUYA", "1" );
try {
DisplayMetrics dm = new DisplayMetrics();
p.getWindowManager().getDefaultDisplay().getMetrics(dm);
float xx = dm.widthPixels/dm.xdpi;
float yy = dm.heightPixels/dm.ydpi;
float x = Math.max(xx, yy);
float y = Math.min(xx, yy);
float displayInches = (float)Math.sqrt( x*x + y*y );
nativeSetEnv( "DISPLAY_SIZE", String.valueOf(displayInches) );
nativeSetEnv( "DISPLAY_SIZE_MM", String.valueOf((int)(displayInches*25.4f)) );
nativeSetEnv( "DISPLAY_WIDTH", String.valueOf(x) );
nativeSetEnv( "DISPLAY_HEIGHT", String.valueOf(y) );
nativeSetEnv( "DISPLAY_WIDTH_MM", String.valueOf((int)(x*25.4f)) );
nativeSetEnv( "DISPLAY_HEIGHT_MM", String.valueOf((int)(y*25.4f)) );
nativeSetEnv( "DISPLAY_RESOLUTION_WIDTH", String.valueOf(Math.max(dm.widthPixels, dm.heightPixels)) );
nativeSetEnv( "DISPLAY_RESOLUTION_HEIGHT", String.valueOf(Math.min(dm.widthPixels, dm.heightPixels)) );
} catch (Exception eeeee) {}
}
static byte [] loadRaw(Activity p, int res)
{
byte [] buf = new byte[65536 * 2];
byte [] a = new byte[65536 * 4 * 10]; // We need 2363516 bytes for the Sun theme
int written = 0;
try{
InputStream is = new GZIPInputStream(p.getResources().openRawResource(res));
int readed = 0;
while( (readed = is.read(buf)) >= 0 )
{
if( written + readed > a.length )
{
byte [] b = new byte [written + readed];
System.arraycopy(a, 0, b, 0, written);
a = b;
}
System.arraycopy(buf, 0, a, written, readed);
written += readed;
}
} catch(Exception e) {};
byte [] b = new byte [written];
System.arraycopy(a, 0, b, 0, written);
return b;
}
static void SetupTouchscreenKeyboardGraphics(Activity p)
{
if( Globals.UseTouchscreenKeyboard )
{
if(Globals.TouchscreenKeyboardTheme < 0)
Globals.TouchscreenKeyboardTheme = 0;
if(Globals.TouchscreenKeyboardTheme > 3)
Globals.TouchscreenKeyboardTheme = 3;
if( Globals.TouchscreenKeyboardTheme == 0 )
{
nativeSetupScreenKeyboardButtons(loadRaw(p, R.raw.ultimatedroid));
}
if( Globals.TouchscreenKeyboardTheme == 1 )
{
nativeSetupScreenKeyboardButtons(loadRaw(p, R.raw.simpletheme));
}
if( Globals.TouchscreenKeyboardTheme == 2 )
{
nativeSetupScreenKeyboardButtons(loadRaw(p, R.raw.sun));
}
if( Globals.TouchscreenKeyboardTheme == 3 )
{
nativeSetupScreenKeyboardButtons(loadRaw(p, R.raw.keen));
}
}
}
abstract static class SdcardAppPath
{
private static SdcardAppPath get()
{
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO)
return Froyo.Holder.sInstance;
else
return Dummy.Holder.sInstance;
}
public abstract String path(final Context p);
public static String deprecatedPath(final Context p)
{
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/app-data/" + p.getPackageName();
}
public static String getPath(final Context p)
{
try {
return get().path(p);
} catch(Exception e) { }
return Dummy.Holder.sInstance.path(p);
}
private static class Froyo extends SdcardAppPath
{
private static class Holder
{
private static final Froyo sInstance = new Froyo();
}
public String path(final Context p)
{
return p.getExternalFilesDir(null).getAbsolutePath();
}
}
private static class Dummy extends SdcardAppPath
{
private static class Holder
{
private static final Dummy sInstance = new Dummy();
}
public String path(final Context p)
{
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + p.getPackageName() + "/files";
}
}
}
static boolean checkRamSize(final MainActivity p)
{
try {
BufferedReader reader = new BufferedReader(new FileReader("/proc/meminfo"));
String line = null;
while( ( line = reader.readLine() ) != null )
{
if( line.indexOf("MemTotal:") == 0 )
{
String[] fields = line.split("[ \t]+");
Long size = Long.parseLong(fields[1]);
Log.i("SDL", "Device RAM size: " + size / 1024 + " Mb, required minimum RAM: " + Globals.AppMinimumRAM + " Mb" );
if( size / 1024 < Globals.AppMinimumRAM )
{
settingsChanged = true;
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.not_enough_ram);
builder.setMessage(p.getResources().getString( R.string.not_enough_ram_size, Globals.AppMinimumRAM, (int)(size / 1024)) );
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
p.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + p.getPackageName())));
System.exit(0);
}
});
builder.setNegativeButton(p.getResources().getString(R.string.ignore), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
SettingsMenu.showConfig(p, true);
return;
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
p.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + p.getPackageName())));
System.exit(0);
}
});
final AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
return false;
}
}
}
} catch ( Exception e ) {
Log.i("SDL", "Error: cannot parse /proc/meminfo: " + e.toString());
}
return true;
}
private static native void nativeSetTrackballUsed();
private static native void nativeSetTrackballDampening(int value);
private static native void nativeSetAccelerometerSettings(int sensitivity, int centerPos);
private static native void nativeSetMouseUsed(int RightClickMethod, int ShowScreenUnderFinger, int LeftClickMethod,
int MoveMouseWithJoystick, int ClickMouseWithDpad, int MaxForce, int MaxRadius,
int MoveMouseWithJoystickSpeed, int MoveMouseWithJoystickAccel,
int leftClickKeycode, int rightClickKeycode,
int leftClickTimeout, int rightClickTimeout,
int relativeMovement, int relativeMovementSpeed,
int relativeMovementAccel, int showMouseCursor);
private static native void nativeSetJoystickUsed(int firstJoystickUsed, int secondJoystickUsed);
private static native void nativeSetAccelerometerUsed();
private static native void nativeSetMultitouchUsed();
private static native void nativeSetTouchscreenKeyboardUsed();
private static native void nativeSetVideoLinearFilter();
private static native void nativeSetVideoDepth(int bpp, int gles2);
private static native void nativeSetCompatibilityHacks();
private static native void nativeSetVideoMultithreaded();
private static native void nativeSetVideoForceSoftwareMode();
private static native void nativeSetupScreenKeyboard(int size, int drawsize, int theme, int nbuttonsAutoFire, int transparency);
private static native void nativeSetupScreenKeyboardButtons(byte[] img);
private static native void nativeInitKeymap();
private static native int nativeGetKeymapKey(int key);
private static native void nativeSetKeymapKey(int javakey, int key);
private static native int nativeGetKeymapKeyScreenKb(int keynum);
private static native void nativeSetKeymapKeyScreenKb(int keynum, int key);
private static native void nativeSetScreenKbKeyUsed(int keynum, int used);
private static native void nativeSetScreenKbKeyLayout(int keynum, int x1, int y1, int x2, int y2);
private static native int nativeGetKeymapKeyMultitouchGesture(int keynum);
private static native void nativeSetKeymapKeyMultitouchGesture(int keynum, int key);
private static native void nativeSetMultitouchGestureSensitivity(int sensitivity);
private static native void nativeSetTouchscreenCalibration(int x1, int y1, int x2, int y2);
public static native void nativeSetEnv(final String name, final String value);
public static native int nativeChmod(final String name, int mode);
public static native void nativeChdir(final String dir);
}

View File

@@ -0,0 +1,257 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.Log;
import java.io.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.StatFs;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.lang.String;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.FrameLayout;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Button;
import android.view.View;
import android.widget.LinearLayout;
import android.text.Editable;
import android.text.SpannedString;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.widget.Toast;
class SettingsMenu
{
public static abstract class Menu
{
// Should be overridden by children
abstract void run(final MainActivity p);
abstract String title(final MainActivity p);
boolean enabled()
{
return true;
}
// Should not be overridden
boolean enabledOrHidden()
{
for( Menu m: Globals.HiddenMenuOptions )
{
if( m.getClass().getName().equals( this.getClass().getName() ) )
return false;
}
return enabled();
}
void showMenuOptionsList(final MainActivity p, final Menu[] list)
{
menuStack.add(this);
ArrayList<CharSequence> items = new ArrayList<CharSequence> ();
for( Menu m: list )
{
if(m.enabledOrHidden())
items.add(m.title(p));
}
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(title(p));
builder.setItems(items.toArray(new CharSequence[0]), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
int selected = 0;
for( Menu m: list )
{
if(m.enabledOrHidden())
{
if( selected == item )
{
m.run(p);
return;
}
selected ++;
}
}
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBackOuterMenu(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static ArrayList<Menu> menuStack = new ArrayList<Menu> ();
public static void showConfig(final MainActivity p, final boolean firstStart)
{
Settings.settingsChanged = true;
if( Globals.OptionalDataDownload == null )
{
String downloads[] = Globals.DataDownloadUrl;
Globals.OptionalDataDownload = new boolean[downloads.length];
boolean oldFormat = true;
for( int i = 0; i < downloads.length; i++ )
{
if( downloads[i].indexOf("!") == 0 )
{
Globals.OptionalDataDownload[i] = true;
oldFormat = false;
}
}
if( oldFormat )
Globals.OptionalDataDownload[0] = true;
}
if(!firstStart)
new MainMenu().run(p);
else
{
if( Globals.StartupMenuButtonTimeout > 0 ) // If we did not disable startup menu altogether
{
for( Menu m: Globals.FirstStartMenuOptions )
{
boolean hidden = false;
for( Menu m1: Globals.HiddenMenuOptions )
{
if( m1.getClass().getName().equals( m.getClass().getName() ) )
hidden = true;
}
if( ! hidden )
menuStack.add(0, m);
}
}
goBack(p);
}
}
static void goBack(final MainActivity p)
{
if(menuStack.isEmpty())
{
Settings.Save(p);
p.startDownloader();
}
else
{
Menu c = menuStack.remove(menuStack.size() - 1);
c.run(p);
}
}
static void goBackOuterMenu(final MainActivity p)
{
if(!menuStack.isEmpty())
menuStack.remove(menuStack.size() - 1);
goBack(p);
}
static class OkButton extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.ok);
}
void run (final MainActivity p)
{
goBackOuterMenu(p);
}
}
static class DummyMenu extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.ok);
}
void run (final MainActivity p)
{
goBack(p);
}
}
static class MainMenu extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.device_config);
}
void run (final MainActivity p)
{
Menu options[] =
{
new SettingsMenuMisc.DownloadConfig(),
new SettingsMenuMisc.OptionalDownloadConfig(false),
new SettingsMenuKeyboard.KeyboardConfigMainMenu(),
new SettingsMenuMouse.MouseConfigMainMenu(),
new SettingsMenuMisc.GyroscopeCalibration(),
new SettingsMenuMisc.AudioConfig(),
new SettingsMenuKeyboard.RemapHwKeysConfig(),
new SettingsMenuKeyboard.ScreenGesturesConfig(),
new SettingsMenuMisc.VideoSettingsConfig(),
new SettingsMenuMisc.ResetToDefaultsConfig(),
new OkButton(),
};
showMenuOptionsList(p, options);
}
}
}

View File

@@ -0,0 +1,843 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.Log;
import java.io.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.StatFs;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.lang.String;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.FrameLayout;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Button;
import android.view.View;
import android.widget.LinearLayout;
import android.text.Editable;
import android.text.SpannedString;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.widget.Toast;
class SettingsMenuKeyboard extends SettingsMenu
{
static class KeyboardConfigMainMenu extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.controls_screenkb);
}
boolean enabled()
{
return Globals.UseTouchscreenKeyboard;
}
void run (final MainActivity p)
{
Menu options[] =
{
new ScreenKeyboardThemeConfig(),
new ScreenKeyboardSizeConfig(),
new ScreenKeyboardDrawSizeConfig(),
new ScreenKeyboardTransparencyConfig(),
new RemapScreenKbConfig(),
new CustomizeScreenKbLayout(),
new OkButton(),
};
showMenuOptionsList(p, options);
}
}
static class ScreenKeyboardSizeConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.controls_screenkb_size);
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_large),
p.getResources().getString(R.string.controls_screenkb_medium),
p.getResources().getString(R.string.controls_screenkb_small),
p.getResources().getString(R.string.controls_screenkb_tiny),
p.getResources().getString(R.string.controls_screenkb_custom) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_size));
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardSize, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.TouchscreenKeyboardSize = item;
dialog.dismiss();
if( Globals.TouchscreenKeyboardSize == Globals.TOUCHSCREEN_KEYBOARD_CUSTOM )
new CustomizeScreenKbLayout().run(p);
else
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class ScreenKeyboardDrawSizeConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.controls_screenkb_drawsize);
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_large),
p.getResources().getString(R.string.controls_screenkb_medium),
p.getResources().getString(R.string.controls_screenkb_small),
p.getResources().getString(R.string.controls_screenkb_tiny) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_drawsize));
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardDrawSize, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.TouchscreenKeyboardDrawSize = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class ScreenKeyboardThemeConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.controls_screenkb_theme);
}
void run (final MainActivity p)
{
final CharSequence[] items = {
p.getResources().getString(R.string.controls_screenkb_by, "Ultimate Droid", "Sean Stieber"),
p.getResources().getString(R.string.controls_screenkb_by, "Simple Theme", "Beholder"),
p.getResources().getString(R.string.controls_screenkb_by, "Sun", "Sirea"),
p.getResources().getString(R.string.controls_screenkb_by, "Keen", "Gerstrong")
};
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_theme));
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardTheme, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.TouchscreenKeyboardTheme = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class ScreenKeyboardTransparencyConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.controls_screenkb_transparency);
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_trans_0),
p.getResources().getString(R.string.controls_screenkb_trans_1),
p.getResources().getString(R.string.controls_screenkb_trans_2),
p.getResources().getString(R.string.controls_screenkb_trans_3),
p.getResources().getString(R.string.controls_screenkb_trans_4) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_transparency));
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardTransparency, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.TouchscreenKeyboardTransparency = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class RemapHwKeysConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.remap_hwkeys);
}
void run (final MainActivity p)
{
p.setText(p.getResources().getString(R.string.remap_hwkeys_press));
p.keyListener = new KeyRemapTool(p);
}
public static class KeyRemapTool implements MainActivity.KeyEventsListener
{
MainActivity p;
public KeyRemapTool(MainActivity _p)
{
p = _p;
}
public void onKeyEvent(final int keyCode)
{
p.keyListener = null;
int keyIndex = keyCode;
if( keyIndex < 0 )
keyIndex = 0;
if( keyIndex > SDL_Keys.JAVA_KEYCODE_LAST )
keyIndex = 0;
final int KeyIndexFinal = keyIndex;
CharSequence[] items = {
SDL_Keys.names[Globals.RemapScreenKbKeycode[0]],
SDL_Keys.names[Globals.RemapScreenKbKeycode[1]],
SDL_Keys.names[Globals.RemapScreenKbKeycode[2]],
SDL_Keys.names[Globals.RemapScreenKbKeycode[3]],
SDL_Keys.names[Globals.RemapScreenKbKeycode[4]],
SDL_Keys.names[Globals.RemapScreenKbKeycode[5]],
p.getResources().getString(R.string.remap_hwkeys_select_more_keys),
};
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
items[i] = Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.remap_hwkeys_select_simple);
builder.setItems(items, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
if( item >= 6 )
ShowAllKeys(KeyIndexFinal);
else
{
Globals.RemapHwKeycode[KeyIndexFinal] = Globals.RemapScreenKbKeycode[item];
goBack(p);
}
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
public void ShowAllKeys(final int KeyIndex)
{
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.remap_hwkeys_select);
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapHwKeycode[KeyIndex]], new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RemapHwKeycode[KeyIndex] = SDL_Keys.namesSortedIdx[item];
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
}
static class RemapScreenKbConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.remap_screenkb);
}
//boolean enabled() { return true; };
void run (final MainActivity p)
{
CharSequence[] items = {
p.getResources().getString(R.string.remap_screenkb_joystick),
p.getResources().getString(R.string.remap_screenkb_button_text),
p.getResources().getString(R.string.remap_screenkb_button) + " 1",
p.getResources().getString(R.string.remap_screenkb_button) + " 2",
p.getResources().getString(R.string.remap_screenkb_button) + " 3",
p.getResources().getString(R.string.remap_screenkb_button) + " 4",
p.getResources().getString(R.string.remap_screenkb_button) + " 5",
p.getResources().getString(R.string.remap_screenkb_button) + " 6",
};
boolean defaults[] = Arrays.copyOf(Globals.ScreenKbControlsShown, Globals.ScreenKbControlsShown.length);
if( Globals.AppUsesSecondJoystick )
{
items = Arrays.copyOf(items, items.length + 1);
items[items.length - 1] = p.getResources().getString(R.string.remap_screenkb_joystick) + " 2";
defaults = Arrays.copyOf(defaults, defaults.length + 1);
defaults[defaults.length - 1] = true;
}
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
items[i+2] = items[i+2] + " - " + Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.remap_screenkb));
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
Globals.ScreenKbControlsShown[item] = isChecked;
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
showRemapScreenKbConfig2(p, 0);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showRemapScreenKbConfig2(final MainActivity p, final int currentButton)
{
CharSequence[] items = {
p.getResources().getString(R.string.remap_screenkb_button) + " 1",
p.getResources().getString(R.string.remap_screenkb_button) + " 2",
p.getResources().getString(R.string.remap_screenkb_button) + " 3",
p.getResources().getString(R.string.remap_screenkb_button) + " 4",
p.getResources().getString(R.string.remap_screenkb_button) + " 5",
p.getResources().getString(R.string.remap_screenkb_button) + " 6",
};
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
items[i] = items[i] + " - " + Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
if( currentButton >= Globals.RemapScreenKbKeycode.length )
{
goBack(p);
return;
}
if( ! Globals.ScreenKbControlsShown[currentButton + 2] )
{
showRemapScreenKbConfig2(p, currentButton + 1);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(items[currentButton]);
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapScreenKbKeycode[currentButton]], new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RemapScreenKbKeycode[currentButton] = SDL_Keys.namesSortedIdx[item];
dialog.dismiss();
showRemapScreenKbConfig2(p, currentButton + 1);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class ScreenGesturesConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.remap_screenkb_button_gestures);
}
//boolean enabled() { return true; };
void run (final MainActivity p)
{
CharSequence[] items = {
p.getResources().getString(R.string.remap_screenkb_button_zoomin),
p.getResources().getString(R.string.remap_screenkb_button_zoomout),
p.getResources().getString(R.string.remap_screenkb_button_rotateleft),
p.getResources().getString(R.string.remap_screenkb_button_rotateright),
};
boolean defaults[] = {
Globals.MultitouchGesturesUsed[0],
Globals.MultitouchGesturesUsed[1],
Globals.MultitouchGesturesUsed[2],
Globals.MultitouchGesturesUsed[3],
};
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.remap_screenkb_button_gestures));
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
Globals.MultitouchGesturesUsed[item] = isChecked;
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
showScreenGesturesConfig2(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showScreenGesturesConfig2(final MainActivity p)
{
final CharSequence[] items = {
p.getResources().getString(R.string.accel_slow),
p.getResources().getString(R.string.accel_medium),
p.getResources().getString(R.string.accel_fast),
p.getResources().getString(R.string.accel_veryfast)
};
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.remap_screenkb_button_gestures_sensitivity);
builder.setSingleChoiceItems(items, Globals.MultitouchGestureSensitivity, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.MultitouchGestureSensitivity = item;
dialog.dismiss();
showScreenGesturesConfig3(p, 0);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showScreenGesturesConfig3(final MainActivity p, final int currentButton)
{
CharSequence[] items = {
p.getResources().getString(R.string.remap_screenkb_button_zoomin),
p.getResources().getString(R.string.remap_screenkb_button_zoomout),
p.getResources().getString(R.string.remap_screenkb_button_rotateleft),
p.getResources().getString(R.string.remap_screenkb_button_rotateright),
};
if( currentButton >= Globals.RemapMultitouchGestureKeycode.length )
{
goBack(p);
return;
}
if( ! Globals.MultitouchGesturesUsed[currentButton] )
{
showScreenGesturesConfig3(p, currentButton + 1);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(items[currentButton]);
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapMultitouchGestureKeycode[currentButton]], new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RemapMultitouchGestureKeycode[currentButton] = SDL_Keys.namesSortedIdx[item];
dialog.dismiss();
showScreenGesturesConfig3(p, currentButton + 1);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class CustomizeScreenKbLayout extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.screenkb_custom_layout);
}
//boolean enabled() { return true; };
void run (final MainActivity p)
{
p.setText(p.getResources().getString(R.string.screenkb_custom_layout_help));
CustomizeScreenKbLayoutTool tool = new CustomizeScreenKbLayoutTool(p);
p.touchListener = tool;
p.keyListener = tool;
Globals.TouchscreenKeyboardSize = Globals.TOUCHSCREEN_KEYBOARD_CUSTOM;
}
static class CustomizeScreenKbLayoutTool implements MainActivity.TouchEventsListener, MainActivity.KeyEventsListener
{
MainActivity p;
FrameLayout layout = null;
ImageView imgs[] = new ImageView[Globals.ScreenKbControlsLayout.length];
Bitmap bmps[] = new Bitmap[Globals.ScreenKbControlsLayout.length];
ImageView boundary = null;
Bitmap boundaryBmp = null;
int currentButton = 0;
int buttons[] = {
R.drawable.dpad,
R.drawable.keyboard,
R.drawable.b1,
R.drawable.b2,
R.drawable.b3,
R.drawable.b4,
R.drawable.b5,
R.drawable.b6,
R.drawable.dpad
};
int oldX = 0, oldY = 0;
boolean resizing = false;
public CustomizeScreenKbLayoutTool(MainActivity _p)
{
p = _p;
layout = new FrameLayout(p);
p.getVideoLayout().addView(layout);
boundary = new ImageView(p);
boundary.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
boundary.setScaleType(ImageView.ScaleType.MATRIX);
boundaryBmp = BitmapFactory.decodeResource( p.getResources(), R.drawable.rectangle );
boundary.setImageBitmap(boundaryBmp);
layout.addView(boundary);
currentButton = -1;
if( Globals.TouchscreenKeyboardTheme == 2 )
{
buttons = new int[] {
R.drawable.sun_dpad,
R.drawable.sun_keyboard,
R.drawable.sun_b1,
R.drawable.sun_b2,
R.drawable.sun_b3,
R.drawable.sun_b4,
R.drawable.sun_b5,
R.drawable.sun_b6,
R.drawable.sun_dpad
};
}
int displayX = 800;
int displayY = 480;
try {
DisplayMetrics dm = new DisplayMetrics();
p.getWindowManager().getDefaultDisplay().getMetrics(dm);
displayX = dm.widthPixels;
displayY = dm.heightPixels;
} catch (Exception eeeee) {}
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
{
if( ! Globals.ScreenKbControlsShown[i] )
continue;
if( currentButton == -1 )
currentButton = i;
//Log.i("SDL", "Screen kb button " + i + " coords " + Globals.ScreenKbControlsLayout[i][0] + ":" + Globals.ScreenKbControlsLayout[i][1] + ":" + Globals.ScreenKbControlsLayout[i][2] + ":" + Globals.ScreenKbControlsLayout[i][3] );
// Check if the button is off screen edge or shrunk to zero
if( Globals.ScreenKbControlsLayout[i][0] > Globals.ScreenKbControlsLayout[i][2] - displayY/12 )
Globals.ScreenKbControlsLayout[i][0] = Globals.ScreenKbControlsLayout[i][2] - displayY/12;
if( Globals.ScreenKbControlsLayout[i][1] > Globals.ScreenKbControlsLayout[i][3] - displayY/12 )
Globals.ScreenKbControlsLayout[i][1] = Globals.ScreenKbControlsLayout[i][3] - displayY/12;
if( Globals.ScreenKbControlsLayout[i][0] < Globals.ScreenKbControlsLayout[i][2] - displayY*2/3 )
Globals.ScreenKbControlsLayout[i][0] = Globals.ScreenKbControlsLayout[i][2] - displayY*2/3;
if( Globals.ScreenKbControlsLayout[i][1] < Globals.ScreenKbControlsLayout[i][3] - displayY*2/3 )
Globals.ScreenKbControlsLayout[i][1] = Globals.ScreenKbControlsLayout[i][3] - displayY*2/3;
if( Globals.ScreenKbControlsLayout[i][0] < 0 )
{
Globals.ScreenKbControlsLayout[i][2] += -Globals.ScreenKbControlsLayout[i][0];
Globals.ScreenKbControlsLayout[i][0] = 0;
}
if( Globals.ScreenKbControlsLayout[i][2] > displayX )
{
Globals.ScreenKbControlsLayout[i][0] -= Globals.ScreenKbControlsLayout[i][2] - displayX;
Globals.ScreenKbControlsLayout[i][2] = displayX;
}
if( Globals.ScreenKbControlsLayout[i][1] < 0 )
{
Globals.ScreenKbControlsLayout[i][3] += -Globals.ScreenKbControlsLayout[i][1];
Globals.ScreenKbControlsLayout[i][1] = 0;
}
if( Globals.ScreenKbControlsLayout[i][3] > displayY )
{
Globals.ScreenKbControlsLayout[i][1] -= Globals.ScreenKbControlsLayout[i][3] - displayY;
Globals.ScreenKbControlsLayout[i][3] = displayY;
}
//Log.i("SDL", "After bounds check coords " + Globals.ScreenKbControlsLayout[i][0] + ":" + Globals.ScreenKbControlsLayout[i][1] + ":" + Globals.ScreenKbControlsLayout[i][2] + ":" + Globals.ScreenKbControlsLayout[i][3] );
imgs[i] = new ImageView(p);
imgs[i].setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
imgs[i].setScaleType(ImageView.ScaleType.MATRIX);
bmps[i] = BitmapFactory.decodeResource( p.getResources(), buttons[i] );
imgs[i].setImageBitmap(bmps[i]);
imgs[i].setAlpha(128);
layout.addView(imgs[i]);
Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmps[i].getWidth(), bmps[i].getHeight());
RectF dst = new RectF(Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][1],
Globals.ScreenKbControlsLayout[i][2], Globals.ScreenKbControlsLayout[i][3]);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
imgs[i].setImageMatrix(m);
}
boundary.bringToFront();
if( currentButton == -1 )
onKeyEvent( KeyEvent.KEYCODE_BACK ); // All buttons disabled - do not show anything
else
setupButton(currentButton);
}
void setupButton(int i)
{
Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmps[i].getWidth(), bmps[i].getHeight());
RectF dst = new RectF(Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][1],
Globals.ScreenKbControlsLayout[i][2], Globals.ScreenKbControlsLayout[i][3]);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
imgs[i].setImageMatrix(m);
m = new Matrix();
src = new RectF(0, 0, boundaryBmp.getWidth(), boundaryBmp.getHeight());
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
boundary.setImageMatrix(m);
String buttonText = "";
if( i >= 2 && i <= 7 )
buttonText = p.getResources().getString(R.string.remap_screenkb_button) + (i - 2);
if( i >= 2 && i - 2 < Globals.AppTouchscreenKeyboardKeysNames.length )
buttonText = Globals.AppTouchscreenKeyboardKeysNames[i - 2].replace("_", " ");
if( i == 0 )
buttonText = "Joystick";
if( i == 1 )
buttonText = "Text input";
if( i == 8 )
buttonText = "Joystick 2";
p.setText(p.getResources().getString(R.string.screenkb_custom_layout_help) + "\n" + buttonText);
}
public void onTouchEvent(final MotionEvent ev)
{
if( ev.getAction() == MotionEvent.ACTION_DOWN )
{
oldX = (int)ev.getX();
oldY = (int)ev.getY();
resizing = true;
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
{
if( ! Globals.ScreenKbControlsShown[i] )
continue;
if( Globals.ScreenKbControlsLayout[i][0] <= oldX &&
Globals.ScreenKbControlsLayout[i][2] >= oldX &&
Globals.ScreenKbControlsLayout[i][1] <= oldY &&
Globals.ScreenKbControlsLayout[i][3] >= oldY )
{
currentButton = i;
setupButton(currentButton);
resizing = false;
break;
}
}
}
if( ev.getAction() == MotionEvent.ACTION_MOVE )
{
int dx = (int)ev.getX() - oldX;
int dy = (int)ev.getY() - oldY;
if( resizing )
{
// Resize slowly, with 1/3 of movement speed
dx /= 6;
dy /= 6;
if( Globals.ScreenKbControlsLayout[currentButton][0] <= Globals.ScreenKbControlsLayout[currentButton][2] + dx*2 )
{
Globals.ScreenKbControlsLayout[currentButton][0] -= dx;
Globals.ScreenKbControlsLayout[currentButton][2] += dx;
}
if( Globals.ScreenKbControlsLayout[currentButton][1] <= Globals.ScreenKbControlsLayout[currentButton][3] + dy*2 )
{
Globals.ScreenKbControlsLayout[currentButton][1] += dy;
Globals.ScreenKbControlsLayout[currentButton][3] -= dy;
}
dx *= 6;
dy *= 6;
}
else
{
Globals.ScreenKbControlsLayout[currentButton][0] += dx;
Globals.ScreenKbControlsLayout[currentButton][2] += dx;
Globals.ScreenKbControlsLayout[currentButton][1] += dy;
Globals.ScreenKbControlsLayout[currentButton][3] += dy;
}
oldX += dx;
oldY += dy;
Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmps[currentButton].getWidth(), bmps[currentButton].getHeight());
RectF dst = new RectF(Globals.ScreenKbControlsLayout[currentButton][0], Globals.ScreenKbControlsLayout[currentButton][1],
Globals.ScreenKbControlsLayout[currentButton][2], Globals.ScreenKbControlsLayout[currentButton][3]);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
imgs[currentButton].setImageMatrix(m);
m = new Matrix();
src = new RectF(0, 0, boundaryBmp.getWidth(), boundaryBmp.getHeight());
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
boundary.setImageMatrix(m);
}
}
public void onKeyEvent(final int keyCode)
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
p.getVideoLayout().removeView(layout);
layout = null;
p.touchListener = null;
p.keyListener = null;
goBack(p);
}
}
}
}
}

View File

@@ -0,0 +1,755 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.Log;
import java.io.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.StatFs;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.lang.String;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.FrameLayout;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Button;
import android.widget.Scroller;
import android.view.View;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.text.Editable;
import android.text.SpannedString;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.widget.Toast;
class SettingsMenuMisc extends SettingsMenu
{
static class DownloadConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.storage_question);
}
void run (final MainActivity p)
{
long freeSdcard = 0;
long freePhone = 0;
try
{
StatFs sdcard = new StatFs(Environment.getExternalStorageDirectory().getPath());
StatFs phone = new StatFs(Environment.getDataDirectory().getPath());
freeSdcard = (long)sdcard.getAvailableBlocks() * sdcard.getBlockSize() / 1024 / 1024;
freePhone = (long)phone.getAvailableBlocks() * phone.getBlockSize() / 1024 / 1024;
}
catch(Exception e) {}
final CharSequence[] items = { p.getResources().getString(R.string.storage_phone, freePhone),
p.getResources().getString(R.string.storage_sd, freeSdcard),
p.getResources().getString(R.string.storage_custom) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.storage_question));
builder.setSingleChoiceItems(items, Globals.DownloadToSdcard ? 1 : 0, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
if( item == 2 )
showCustomDownloadDirConfig(p);
else
{
Globals.DownloadToSdcard = (item != 0);
Globals.DataDir = Globals.DownloadToSdcard ?
Settings.SdcardAppPath.getPath(p) :
p.getFilesDir().getAbsolutePath();
goBack(p);
}
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showCustomDownloadDirConfig(final MainActivity p)
{
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.storage_custom));
final EditText edit = new EditText(p);
edit.setFocusableInTouchMode(true);
edit.setFocusable(true);
edit.setText(Globals.DataDir);
builder.setView(edit);
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.DataDir = edit.getText().toString();
dialog.dismiss();
showCommandLineConfig(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showCommandLineConfig(final MainActivity p)
{
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.storage_commandline));
final EditText edit = new EditText(p);
edit.setFocusableInTouchMode(true);
edit.setFocusable(true);
edit.setText(Globals.CommandLine);
builder.setView(edit);
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.CommandLine = edit.getText().toString();
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class OptionalDownloadConfig extends Menu
{
boolean firstStart = false;
OptionalDownloadConfig()
{
firstStart = true;
}
OptionalDownloadConfig(boolean firstStart)
{
this.firstStart = firstStart;
}
String title(final MainActivity p)
{
return p.getResources().getString(R.string.downloads);
}
void run (final MainActivity p)
{
String [] downloadFiles = Globals.DataDownloadUrl;
final boolean [] mandatory = new boolean[downloadFiles.length];
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.downloads));
CharSequence[] items = new CharSequence[downloadFiles.length];
for(int i = 0; i < downloadFiles.length; i++ )
{
items[i] = new String(downloadFiles[i].split("[|]")[0]);
if( items[i].toString().indexOf("!") == 0 )
items[i] = items[i].toString().substring(1);
if( items[i].toString().indexOf("!") == 0 )
{
items[i] = items[i].toString().substring(1);
mandatory[i] = true;
}
}
if( Globals.OptionalDataDownload == null || Globals.OptionalDataDownload.length != items.length )
{
Globals.OptionalDataDownload = new boolean[downloadFiles.length];
boolean oldFormat = true;
for( int i = 0; i < downloadFiles.length; i++ )
{
if( downloadFiles[i].indexOf("!") == 0 )
{
Globals.OptionalDataDownload[i] = true;
oldFormat = false;
}
}
if( oldFormat )
{
Globals.OptionalDataDownload[0] = true;
mandatory[0] = true;
}
}
builder.setMultiChoiceItems(items, Globals.OptionalDataDownload, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
Globals.OptionalDataDownload[item] = isChecked;
if( mandatory[item] && !isChecked )
{
Globals.OptionalDataDownload[item] = true;
((AlertDialog)dialog).getListView().setItemChecked(item, true);
}
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
goBack(p);
}
});
if( firstStart )
{
builder.setNegativeButton(p.getResources().getString(R.string.show_more_options), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
menuStack.clear();
new MainMenu().run(p);
}
});
}
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class AudioConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.audiobuf_question);
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.audiobuf_verysmall),
p.getResources().getString(R.string.audiobuf_small),
p.getResources().getString(R.string.audiobuf_medium),
p.getResources().getString(R.string.audiobuf_large) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.audiobuf_question);
builder.setSingleChoiceItems(items, Globals.AudioBufferConfig, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.AudioBufferConfig = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class VideoSettingsConfig extends Menu
{
static int debugMenuShowCount = 0;
String title(final MainActivity p)
{
return p.getResources().getString(R.string.video);
}
//boolean enabled() { return true; };
void run (final MainActivity p)
{
debugMenuShowCount++;
CharSequence[] items = {
p.getResources().getString(R.string.pointandclick_keepaspectratio),
p.getResources().getString(R.string.video_smooth)
};
boolean defaults[] = {
Globals.KeepAspectRatio,
Globals.VideoLinearFilter
};
if(Globals.SwVideoMode && !Globals.CompatibilityHacksVideo)
{
CharSequence[] items2 = {
p.getResources().getString(R.string.pointandclick_keepaspectratio),
p.getResources().getString(R.string.video_smooth),
p.getResources().getString(R.string.video_separatethread),
};
boolean defaults2[] = {
Globals.KeepAspectRatio,
Globals.VideoLinearFilter,
Globals.MultiThreadedVideo
};
items = items2;
defaults = defaults2;
}
if(Globals.Using_SDL_1_3)
{
CharSequence[] items2 = {
p.getResources().getString(R.string.pointandclick_keepaspectratio),
};
boolean defaults2[] = {
Globals.KeepAspectRatio,
};
items = items2;
defaults = defaults2;
}
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.video));
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
if( item == 0 )
Globals.KeepAspectRatio = isChecked;
if( item == 1 )
Globals.VideoLinearFilter = isChecked;
if( item == 2 )
Globals.MultiThreadedVideo = isChecked;
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
if( debugMenuShowCount > 5 || Globals.OuyaEmulation )
showDebugMenu(p);
else
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
void showDebugMenu (final MainActivity p)
{
CharSequence[] items = {
"OUYA emulation"
};
boolean defaults[] = {
Globals.OuyaEmulation,
};
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle("Debug settings");
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
if( item == 0 )
Globals.OuyaEmulation = isChecked;
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class ShowReadme extends Menu
{
String title(final MainActivity p)
{
return "Readme";
}
boolean enabled()
{
return true;
}
void run (final MainActivity p)
{
String readmes[] = Globals.ReadmeText.split("\\^");
String lang = new String(Locale.getDefault().getLanguage()) + ":";
if( p.isRunningOnOUYA() )
lang = "ouya:";
String readme = readmes[0];
String buttonName = "", buttonUrl = "";
for( String r: readmes )
{
if( r.startsWith(lang) )
readme = r.substring(lang.length());
if( r.startsWith("button:") )
{
buttonName = r.substring("button:".length());
if( buttonName.indexOf(":") != -1 )
{
buttonUrl = buttonName.substring(buttonName.indexOf(":") + 1);
buttonName = buttonName.substring(0, buttonName.indexOf(":"));
}
}
}
readme = readme.trim();
if( readme.length() <= 2 )
{
goBack(p);
return;
}
TextView text = new TextView(p);
text.setMaxLines(100);
//text.setScroller(new Scroller(p));
//text.setVerticalScrollBarEnabled(true);
text.setText(readme);
text.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
text.setPadding(0, 5, 0, 20);
text.setTextSize(20.0f);
text.setGravity(Gravity.CENTER);
AlertDialog.Builder builder = new AlertDialog.Builder(p);
ScrollView scroll = new ScrollView(p);
scroll.addView(text, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Button ok = new Button(p);
final AlertDialog alertDismiss[] = new AlertDialog[1];
ok.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
alertDismiss[0].cancel();
}
});
ok.setText(R.string.ok);
LinearLayout layout = new LinearLayout(p);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(scroll);
//layout.addView(text);
layout.addView(ok);
if( buttonName.length() > 0 )
{
Button cancel = new Button(p);
cancel.setText(buttonName);
final String url = buttonUrl;
cancel.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if( url.length() > 0 )
{
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
p.startActivity(i);
}
alertDismiss[0].cancel();
System.exit(0);
}
});
layout.addView(cancel);
}
builder.setView(layout);
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alertDismiss[0] = alert;
alert.setOwnerActivity(p);
alert.show();
}
}
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) )
{
if( Globals.AppUsesGyroscope )
{
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 = 0;
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 + "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 * 1.1f); // Small safety bound coefficient
AccelerometerReader.gyro.x2 = Math.max(AccelerometerReader.gyro.x2, x * 1.1f);
AccelerometerReader.gyro.y1 = Math.min(AccelerometerReader.gyro.y1, y * 1.1f);
AccelerometerReader.gyro.y2 = Math.max(AccelerometerReader.gyro.y2, y * 1.1f);
AccelerometerReader.gyro.z1 = Math.min(AccelerometerReader.gyro.z1, z * 1.1f);
AccelerometerReader.gyro.z2 = Math.max(AccelerometerReader.gyro.z2, z * 1.1f);
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 > 5 )
{
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);
}
});
}
}
static class ResetToDefaultsConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.reset_config);
}
boolean enabled()
{
return true;
}
void run (final MainActivity p)
{
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.reset_config_ask));
builder.setMessage(p.getResources().getString(R.string.reset_config_ask));
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Settings.DeleteSdlConfigOnUpgradeAndRestart(p); // Never returns
dialog.dismiss();
goBack(p);
}
});
builder.setNegativeButton(p.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
}

View File

@@ -0,0 +1,771 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.util.Log;
import java.io.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Environment;
import android.os.StatFs;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.lang.String;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.FrameLayout;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Button;
import android.view.View;
import android.widget.LinearLayout;
import android.text.Editable;
import android.text.SpannedString;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.util.DisplayMetrics;
import android.net.Uri;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
import android.graphics.Color;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.widget.Toast;
class SettingsMenuMouse extends SettingsMenu
{
static class MouseConfigMainMenu extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.mouse_emulation);
}
boolean enabled()
{
return Globals.AppUsesMouse;
}
void run (final MainActivity p)
{
Menu options[] =
{
new DisplaySizeConfig(false),
new LeftClickConfig(),
new RightClickConfig(),
new AdditionalMouseConfig(),
new JoystickMouseConfig(),
new TouchPressureMeasurementTool(),
new CalibrateTouchscreenMenu(),
new OkButton(),
};
showMenuOptionsList(p, options);
}
}
static class DisplaySizeConfig extends Menu
{
boolean firstStart = false;
DisplaySizeConfig()
{
this.firstStart = true;
}
DisplaySizeConfig(boolean firstStart)
{
this.firstStart = firstStart;
}
String title(final MainActivity p)
{
return p.getResources().getString(R.string.display_size_mouse);
}
void run (final MainActivity p)
{
CharSequence[] items = {
p.getResources().getString(R.string.display_size_tiny_touchpad),
p.getResources().getString(R.string.display_size_tiny),
p.getResources().getString(R.string.display_size_small),
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
};
int _size_tiny_touchpad = 0;
int _size_tiny = 1;
int _size_small = 2;
int _size_small_touchpad = 3;
int _size_large = 4;
int _more_options = 5;
if( ! Globals.SwVideoMode )
{
CharSequence[] items2 = {
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
};
items = items2;
_size_small_touchpad = 0;
_size_large = 1;
_size_tiny_touchpad = _size_tiny = _size_small = 1000;
}
if( firstStart )
{
CharSequence[] items2 = {
p.getResources().getString(R.string.display_size_tiny_touchpad),
p.getResources().getString(R.string.display_size_tiny),
p.getResources().getString(R.string.display_size_small),
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
p.getResources().getString(R.string.show_more_options),
};
items = items2;
if( ! Globals.SwVideoMode )
{
CharSequence[] items3 = {
p.getResources().getString(R.string.display_size_small_touchpad),
p.getResources().getString(R.string.display_size_large),
p.getResources().getString(R.string.show_more_options),
};
items = items3;
_more_options = 3;
}
}
// Java is so damn worse than C++11
final int size_tiny_touchpad = _size_tiny_touchpad;
final int size_tiny = _size_tiny;
final int size_small = _size_small;
final int size_small_touchpad = _size_small_touchpad;
final int size_large = _size_large;
final int more_options = _more_options;
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.display_size);
class ClickListener implements DialogInterface.OnClickListener
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
if( item == size_large )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL;
Globals.RelativeMouseMovement = false;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
}
if( item == size_small )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR;
Globals.RelativeMouseMovement = false;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_MAGNIFIER;
}
if( item == size_small_touchpad )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
Globals.RelativeMouseMovement = true;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
}
if( item == size_tiny )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR;
Globals.RelativeMouseMovement = false;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_SCREEN_TRANSFORM;
}
if( item == size_tiny_touchpad )
{
Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
Globals.RelativeMouseMovement = true;
Globals.ShowScreenUnderFinger = Mouse.ZOOM_FULLSCREEN_MAGNIFIER;
}
if( item == more_options )
{
menuStack.clear();
new MainMenu().run(p);
return;
}
goBack(p);
}
}
builder.setItems(items, new ClickListener());
/*
else
builder.setSingleChoiceItems(items,
Globals.ShowScreenUnderFinger == Mouse.ZOOM_NONE ?
( Globals.RelativeMouseMovement ? Globals.SwVideoMode ? 2 : 1 : 0 ) :
( Globals.ShowScreenUnderFinger == Mouse.ZOOM_MAGNIFIER && Globals.SwVideoMode ) ? 1 :
Globals.ShowScreenUnderFinger + 1,
new ClickListener());
*/
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class LeftClickConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.leftclick_question);
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_normal),
p.getResources().getString(R.string.leftclick_near_cursor),
p.getResources().getString(R.string.leftclick_multitouch),
p.getResources().getString(R.string.leftclick_pressure),
p.getResources().getString(R.string.rightclick_key),
p.getResources().getString(R.string.leftclick_timeout),
p.getResources().getString(R.string.leftclick_tap),
p.getResources().getString(R.string.leftclick_tap_or_timeout) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.leftclick_question);
builder.setSingleChoiceItems(items, Globals.LeftClickMethod, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
Globals.LeftClickMethod = item;
if( item == Mouse.LEFT_CLICK_WITH_KEY )
p.keyListener = new KeyRemapToolMouseClick(p, true);
else if( item == Mouse.LEFT_CLICK_WITH_TIMEOUT || item == Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT )
showLeftClickTimeoutConfig(p);
else
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showLeftClickTimeoutConfig(final MainActivity p) {
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_timeout_time_0),
p.getResources().getString(R.string.leftclick_timeout_time_1),
p.getResources().getString(R.string.leftclick_timeout_time_2),
p.getResources().getString(R.string.leftclick_timeout_time_3),
p.getResources().getString(R.string.leftclick_timeout_time_4) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.leftclick_timeout_time);
builder.setSingleChoiceItems(items, Globals.LeftClickTimeout, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.LeftClickTimeout = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class RightClickConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.rightclick_question);
}
boolean enabled()
{
return Globals.AppNeedsTwoButtonMouse;
}
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.rightclick_none),
p.getResources().getString(R.string.rightclick_multitouch),
p.getResources().getString(R.string.rightclick_pressure),
p.getResources().getString(R.string.rightclick_key),
p.getResources().getString(R.string.leftclick_timeout) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.rightclick_question);
builder.setSingleChoiceItems(items, Globals.RightClickMethod, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RightClickMethod = item;
dialog.dismiss();
if( item == Mouse.RIGHT_CLICK_WITH_KEY )
p.keyListener = new KeyRemapToolMouseClick(p, false);
else if( item == Mouse.RIGHT_CLICK_WITH_TIMEOUT )
showRightClickTimeoutConfig(p);
else
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showRightClickTimeoutConfig(final MainActivity p) {
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_timeout_time_0),
p.getResources().getString(R.string.leftclick_timeout_time_1),
p.getResources().getString(R.string.leftclick_timeout_time_2),
p.getResources().getString(R.string.leftclick_timeout_time_3),
p.getResources().getString(R.string.leftclick_timeout_time_4) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.leftclick_timeout_time);
builder.setSingleChoiceItems(items, Globals.RightClickTimeout, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RightClickTimeout = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
public static class KeyRemapToolMouseClick implements MainActivity.KeyEventsListener
{
MainActivity p;
boolean leftClick;
public KeyRemapToolMouseClick(MainActivity _p, boolean leftClick)
{
p = _p;
p.setText(p.getResources().getString(R.string.remap_hwkeys_press));
this.leftClick = leftClick;
}
public void onKeyEvent(final int keyCode)
{
p.keyListener = null;
int keyIndex = keyCode;
if( keyIndex < 0 )
keyIndex = 0;
if( keyIndex > SDL_Keys.JAVA_KEYCODE_LAST )
keyIndex = 0;
if( leftClick )
Globals.LeftClickKey = keyIndex;
else
Globals.RightClickKey = keyIndex;
goBack(p);
}
}
static class AdditionalMouseConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.pointandclick_question);
}
void run (final MainActivity p)
{
CharSequence[] items = {
p.getResources().getString(R.string.pointandclick_joystickmouse),
p.getResources().getString(R.string.click_with_dpadcenter),
p.getResources().getString(R.string.pointandclick_relative)
};
boolean defaults[] = {
Globals.MoveMouseWithJoystick,
Globals.ClickMouseWithDpad,
Globals.RelativeMouseMovement
};
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(p.getResources().getString(R.string.pointandclick_question));
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
{
public void onClick(DialogInterface dialog, int item, boolean isChecked)
{
if( item == 0 )
Globals.MoveMouseWithJoystick = isChecked;
if( item == 1 )
Globals.ClickMouseWithDpad = isChecked;
if( item == 2 )
Globals.RelativeMouseMovement = isChecked;
}
});
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
dialog.dismiss();
if( Globals.RelativeMouseMovement )
showRelativeMouseMovementConfig(p);
else
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showRelativeMouseMovementConfig(final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.accel_veryslow),
p.getResources().getString(R.string.accel_slow),
p.getResources().getString(R.string.accel_medium),
p.getResources().getString(R.string.accel_fast),
p.getResources().getString(R.string.accel_veryfast) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.pointandclick_relative_speed);
builder.setSingleChoiceItems(items, Globals.RelativeMouseMovementSpeed, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RelativeMouseMovementSpeed = item;
dialog.dismiss();
showRelativeMouseMovementConfig1(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showRelativeMouseMovementConfig1(final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.none),
p.getResources().getString(R.string.accel_slow),
p.getResources().getString(R.string.accel_medium),
p.getResources().getString(R.string.accel_fast) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.pointandclick_relative_accel);
builder.setSingleChoiceItems(items, Globals.RelativeMouseMovementAccel, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.RelativeMouseMovementAccel = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class JoystickMouseConfig extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.pointandclick_joystickmousespeed);
}
boolean enabled()
{
return Globals.MoveMouseWithJoystick;
};
void run (final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.accel_slow),
p.getResources().getString(R.string.accel_medium),
p.getResources().getString(R.string.accel_fast) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.pointandclick_joystickmousespeed);
builder.setSingleChoiceItems(items, Globals.MoveMouseWithJoystickSpeed, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.MoveMouseWithJoystickSpeed = item;
dialog.dismiss();
showJoystickMouseAccelConfig(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
static void showJoystickMouseAccelConfig(final MainActivity p)
{
final CharSequence[] items = { p.getResources().getString(R.string.none),
p.getResources().getString(R.string.accel_slow),
p.getResources().getString(R.string.accel_medium),
p.getResources().getString(R.string.accel_fast) };
AlertDialog.Builder builder = new AlertDialog.Builder(p);
builder.setTitle(R.string.pointandclick_joystickmouseaccel);
builder.setSingleChoiceItems(items, Globals.MoveMouseWithJoystickAccel, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
Globals.MoveMouseWithJoystickAccel = item;
dialog.dismiss();
goBack(p);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
goBack(p);
}
});
AlertDialog alert = builder.create();
alert.setOwnerActivity(p);
alert.show();
}
}
static class TouchPressureMeasurementTool extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.measurepressure);
}
boolean enabled()
{
return Globals.RightClickMethod == Mouse.RIGHT_CLICK_WITH_PRESSURE ||
Globals.LeftClickMethod == Mouse.LEFT_CLICK_WITH_PRESSURE;
};
void run (final MainActivity p)
{
p.setText(p.getResources().getString(R.string.measurepressure_touchplease));
p.touchListener = new TouchMeasurementTool(p);
}
public static class TouchMeasurementTool implements MainActivity.TouchEventsListener
{
MainActivity p;
ArrayList<Integer> force = new ArrayList<Integer>();
ArrayList<Integer> radius = new ArrayList<Integer>();
static final int maxEventAmount = 100;
public TouchMeasurementTool(MainActivity _p)
{
p = _p;
}
public void onTouchEvent(final MotionEvent ev)
{
force.add(new Integer((int)(ev.getPressure() * 1000.0)));
radius.add(new Integer((int)(ev.getSize() * 1000.0)));
p.setText(p.getResources().getString(R.string.measurepressure_response, force.get(force.size()-1), radius.get(radius.size()-1)));
try {
Thread.sleep(10L);
} catch (InterruptedException e) { }
if( force.size() >= maxEventAmount )
{
p.touchListener = null;
Globals.ClickScreenPressure = getAverageForce();
Globals.ClickScreenTouchspotSize = getAverageRadius();
Log.i("SDL", "SDL: measured average force " + Globals.ClickScreenPressure + " radius " + Globals.ClickScreenTouchspotSize);
goBack(p);
}
}
int getAverageForce()
{
int avg = 0;
for(Integer f: force)
{
avg += f;
}
return avg / force.size();
}
int getAverageRadius()
{
int avg = 0;
for(Integer r: radius)
{
avg += r;
}
return avg / radius.size();
}
}
}
static class CalibrateTouchscreenMenu extends Menu
{
String title(final MainActivity p)
{
return p.getResources().getString(R.string.calibrate_touchscreen);
}
//boolean enabled() { return true; };
void run (final MainActivity p)
{
p.setText(p.getResources().getString(R.string.calibrate_touchscreen_touch));
Globals.TouchscreenCalibration[0] = 0;
Globals.TouchscreenCalibration[1] = 0;
Globals.TouchscreenCalibration[2] = 0;
Globals.TouchscreenCalibration[3] = 0;
ScreenEdgesCalibrationTool tool = new ScreenEdgesCalibrationTool(p);
p.touchListener = tool;
p.keyListener = tool;
}
static class ScreenEdgesCalibrationTool implements MainActivity.TouchEventsListener, MainActivity.KeyEventsListener
{
MainActivity p;
ImageView img;
Bitmap bmp;
public ScreenEdgesCalibrationTool(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(Globals.TouchscreenCalibration[0], Globals.TouchscreenCalibration[1],
Globals.TouchscreenCalibration[2], Globals.TouchscreenCalibration[3]);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
img.setImageMatrix(m);
p.getVideoLayout().addView(img);
}
public void onTouchEvent(final MotionEvent ev)
{
if( Globals.TouchscreenCalibration[0] == Globals.TouchscreenCalibration[1] &&
Globals.TouchscreenCalibration[1] == Globals.TouchscreenCalibration[2] &&
Globals.TouchscreenCalibration[2] == Globals.TouchscreenCalibration[3] )
{
Globals.TouchscreenCalibration[0] = (int)ev.getX();
Globals.TouchscreenCalibration[1] = (int)ev.getY();
Globals.TouchscreenCalibration[2] = (int)ev.getX();
Globals.TouchscreenCalibration[3] = (int)ev.getY();
}
if( ev.getX() < Globals.TouchscreenCalibration[0] )
Globals.TouchscreenCalibration[0] = (int)ev.getX();
if( ev.getY() < Globals.TouchscreenCalibration[1] )
Globals.TouchscreenCalibration[1] = (int)ev.getY();
if( ev.getX() > Globals.TouchscreenCalibration[2] )
Globals.TouchscreenCalibration[2] = (int)ev.getX();
if( ev.getY() > Globals.TouchscreenCalibration[3] )
Globals.TouchscreenCalibration[3] = (int)ev.getY();
Matrix m = new Matrix();
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
RectF dst = new RectF(Globals.TouchscreenCalibration[0], Globals.TouchscreenCalibration[1],
Globals.TouchscreenCalibration[2], Globals.TouchscreenCalibration[3]);
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
img.setImageMatrix(m);
}
public void onKeyEvent(final int keyCode)
{
p.touchListener = null;
p.keyListener = null;
p.getVideoLayout().removeView(img);
goBack(p);
}
}
}
}

845
project/javaSDL2/Video.java Normal file
View File

@@ -0,0 +1,845 @@
/*
Simple DirectMedia Layer
Java source code (C) 2009-2012 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
package net.sourceforge.clonekeenplus;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.InputDevice;
import android.view.Window;
import android.view.WindowManager;
import android.os.Environment;
import java.io.File;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.content.res.Resources;
import android.content.res.AssetManager;
import android.widget.Toast;
import android.util.Log;
import android.widget.TextView;
import java.lang.Thread;
import java.util.concurrent.locks.ReentrantLock;
import android.os.Build;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
class Mouse
{
public static final int LEFT_CLICK_NORMAL = 0;
public static final int LEFT_CLICK_NEAR_CURSOR = 1;
public static final int LEFT_CLICK_WITH_MULTITOUCH = 2;
public static final int LEFT_CLICK_WITH_PRESSURE = 3;
public static final int LEFT_CLICK_WITH_KEY = 4;
public static final int LEFT_CLICK_WITH_TIMEOUT = 5;
public static final int LEFT_CLICK_WITH_TAP = 6;
public static final int LEFT_CLICK_WITH_TAP_OR_TIMEOUT = 7;
public static final int RIGHT_CLICK_NONE = 0;
public static final int RIGHT_CLICK_WITH_MULTITOUCH = 1;
public static final int RIGHT_CLICK_WITH_PRESSURE = 2;
public static final int RIGHT_CLICK_WITH_KEY = 3;
public static final int RIGHT_CLICK_WITH_TIMEOUT = 4;
public static final int SDL_FINGER_DOWN = 0;
public static final int SDL_FINGER_UP = 1;
public static final int SDL_FINGER_MOVE = 2;
public static final int SDL_FINGER_HOVER = 3;
public static final int ZOOM_NONE = 0;
public static final int ZOOM_MAGNIFIER = 1;
public static final int ZOOM_SCREEN_TRANSFORM = 2;
public static final int ZOOM_FULLSCREEN_MAGNIFIER = 3;
}
abstract class DifferentTouchInput
{
public abstract void process(final MotionEvent event);
public abstract void processGenericEvent(final MotionEvent event);
public static boolean ExternalMouseDetected = false;
public static DifferentTouchInput getInstance()
{
boolean multiTouchAvailable1 = false;
boolean multiTouchAvailable2 = false;
// Not checking for getX(int), getY(int) etc 'cause I'm lazy
Method methods [] = MotionEvent.class.getDeclaredMethods();
for(Method m: methods)
{
if( m.getName().equals("getPointerCount") )
multiTouchAvailable1 = true;
if( m.getName().equals("getPointerId") )
multiTouchAvailable2 = true;
}
try {
Log.i("SDL", "Device model: " + android.os.Build.MODEL);
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH )
{
if( DetectCrappyDragonRiseDatexGamepad() )
return CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad.Holder.sInstance;
return IcsTouchInput.Holder.sInstance;
}
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD )
return GingerbreadTouchInput.Holder.sInstance;
if (multiTouchAvailable1 && multiTouchAvailable2)
return MultiTouchInput.Holder.sInstance;
else
return SingleTouchInput.Holder.sInstance;
} catch( Exception e ) {
try {
if (multiTouchAvailable1 && multiTouchAvailable2)
return MultiTouchInput.Holder.sInstance;
else
return SingleTouchInput.Holder.sInstance;
} catch( Exception ee ) {
return SingleTouchInput.Holder.sInstance;
}
}
}
private static boolean DetectCrappyDragonRiseDatexGamepad()
{
if( CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad.Holder.sInstance == null )
return false;
return CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad.Holder.sInstance.detect();
}
private static class SingleTouchInput extends DifferentTouchInput
{
private static class Holder
{
private static final SingleTouchInput sInstance = new SingleTouchInput();
}
@Override
public void processGenericEvent(final MotionEvent event)
{
process(event);
}
public void process(final MotionEvent event)
{
int action = -1;
if( event.getAction() == MotionEvent.ACTION_DOWN )
action = Mouse.SDL_FINGER_DOWN;
if( event.getAction() == MotionEvent.ACTION_UP )
action = Mouse.SDL_FINGER_UP;
if( event.getAction() == MotionEvent.ACTION_MOVE )
action = Mouse.SDL_FINGER_MOVE;
if ( action >= 0 )
DemoGLSurfaceView.nativeMotionEvent( (int)event.getX(), (int)event.getY(), action, 0,
(int)(event.getPressure() * 1000.0),
(int)(event.getSize() * 1000.0) );
}
}
private static class MultiTouchInput extends DifferentTouchInput
{
public static final int TOUCH_EVENTS_MAX = 16; // Max multitouch pointers
private class touchEvent
{
public boolean down = false;
public int x = 0;
public int y = 0;
public int pressure = 0;
public int size = 0;
}
protected touchEvent touchEvents[];
MultiTouchInput()
{
touchEvents = new touchEvent[TOUCH_EVENTS_MAX];
for( int i = 0; i < TOUCH_EVENTS_MAX; i++ )
touchEvents[i] = new touchEvent();
}
private static class Holder
{
private static final MultiTouchInput sInstance = new MultiTouchInput();
}
public void processGenericEvent(final MotionEvent event)
{
process(event);
}
public void process(final MotionEvent event)
{
int action = -1;
//Log.i("SDL", "Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY());
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP ||
(event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_CANCEL )
{
action = Mouse.SDL_FINGER_UP;
for( int i = 0; i < TOUCH_EVENTS_MAX; i++ )
{
if( touchEvents[i].down )
{
touchEvents[i].down = false;
DemoGLSurfaceView.nativeMotionEvent( touchEvents[i].x, touchEvents[i].y, action, i, touchEvents[i].pressure, touchEvents[i].size );
}
}
}
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN )
{
action = Mouse.SDL_FINGER_DOWN;
for( int i = 0; i < event.getPointerCount(); i++ )
{
int id = event.getPointerId(i);
if( id >= TOUCH_EVENTS_MAX )
id = TOUCH_EVENTS_MAX - 1;
touchEvents[id].down = true;
touchEvents[id].x = (int)event.getX(i);
touchEvents[id].y = (int)event.getY(i);
touchEvents[id].pressure = (int)(event.getPressure(i) * 1000.0);
touchEvents[id].size = (int)(event.getSize(i) * 1000.0);
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE ||
(event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN ||
(event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP )
{
/*
String s = "MOVE: ptrs " + event.getPointerCount();
for( int i = 0 ; i < event.getPointerCount(); i++ )
{
s += " p" + event.getPointerId(i) + "=" + (int)event.getX(i) + ":" + (int)event.getY(i);
}
Log.i("SDL", s);
*/
int pointerReleased = -1;
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP )
pointerReleased = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
for( int id = 0; id < TOUCH_EVENTS_MAX; id++ )
{
int ii;
for( ii = 0; ii < event.getPointerCount(); ii++ )
{
if( id == event.getPointerId(ii) )
break;
}
if( ii >= event.getPointerCount() )
{
// Up event
if( touchEvents[id].down )
{
action = Mouse.SDL_FINGER_UP;
touchEvents[id].down = false;
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
else
{
if( pointerReleased == id && touchEvents[pointerReleased].down )
{
action = Mouse.SDL_FINGER_UP;
touchEvents[id].down = false;
}
else if( touchEvents[id].down )
{
action = Mouse.SDL_FINGER_MOVE;
}
else
{
action = Mouse.SDL_FINGER_DOWN;
touchEvents[id].down = true;
}
touchEvents[id].x = (int)event.getX(ii);
touchEvents[id].y = (int)event.getY(ii);
touchEvents[id].pressure = (int)(event.getPressure(ii) * 1000.0);
touchEvents[id].size = (int)(event.getSize(ii) * 1000.0);
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
}
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_HOVER_MOVE ) // Support bluetooth/USB mouse - available since Android 3.1
{
// TODO: it is possible that multiple pointers return that event, but we're handling only pointer #0
if( touchEvents[0].down )
action = Mouse.SDL_FINGER_UP;
else
action = Mouse.SDL_FINGER_HOVER;
touchEvents[0].down = false;
touchEvents[0].x = (int)event.getX();
touchEvents[0].y = (int)event.getY();
touchEvents[0].pressure = 0;
touchEvents[0].size = 0;
DemoGLSurfaceView.nativeMotionEvent( touchEvents[0].x, touchEvents[0].y, action, 0, touchEvents[0].pressure, touchEvents[0].size );
}
}
}
private static class GingerbreadTouchInput extends MultiTouchInput
{
private static class Holder
{
private static final GingerbreadTouchInput sInstance = new GingerbreadTouchInput();
}
GingerbreadTouchInput()
{
super();
}
public void process(final MotionEvent event)
{
boolean hwMouseEvent = ( (event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
(event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS ||
(event.getMetaState() & KeyEvent.FLAG_TRACKING) != 0 ); // Hack to recognize Galaxy Note Gingerbread stylus
if( ExternalMouseDetected != hwMouseEvent )
{
ExternalMouseDetected = hwMouseEvent;
DemoGLSurfaceView.nativeHardwareMouseDetected(hwMouseEvent ? 1 : 0);
}
super.process(event);
}
public void processGenericEvent(final MotionEvent event)
{
process(event);
}
}
private static class IcsTouchInput extends GingerbreadTouchInput
{
private static class Holder
{
private static final IcsTouchInput sInstance = new IcsTouchInput();
}
private int buttonState = 0;
public void process(final MotionEvent event)
{
//Log.i("SDL", "Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY() + " buttons " + buttonState + " source " + event.getSource());
int buttonStateNew = event.getButtonState();
if( buttonStateNew != buttonState )
{
for( int i = 1; i <= MotionEvent.BUTTON_FORWARD; i *= 2 )
{
if( (buttonStateNew & i) != (buttonState & i) )
DemoGLSurfaceView.nativeMouseButtonsPressed(i, ((buttonStateNew & i) == 0) ? 0 : 1);
}
buttonState = buttonStateNew;
}
super.process(event); // Push mouse coordinate first
}
public void processGenericEvent(final MotionEvent event)
{
// Joysticks are supported since Honeycomb, but I don't care about it, because very little devices have it
if( (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK )
{
DemoGLSurfaceView.nativeGamepadAnalogJoystickInput(
event.getAxisValue(MotionEvent.AXIS_X), event.getAxisValue(MotionEvent.AXIS_Y),
event.getAxisValue(MotionEvent.AXIS_Z), event.getAxisValue(MotionEvent.AXIS_RZ),
event.getAxisValue(MotionEvent.AXIS_RTRIGGER), event.getAxisValue(MotionEvent.AXIS_LTRIGGER) );
return;
}
// Process mousewheel
if( event.getAction() == MotionEvent.ACTION_SCROLL )
{
int scrollX = Math.round(event.getAxisValue(MotionEvent.AXIS_HSCROLL));
int scrollY = Math.round(event.getAxisValue(MotionEvent.AXIS_VSCROLL));
DemoGLSurfaceView.nativeMouseWheel(scrollX, scrollY);
return;
}
super.processGenericEvent(event);
}
}
private static class CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad extends IcsTouchInput
{
private static class Holder
{
private static final CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad sInstance = new CrappyDragonRiseDatexGamepadInputWhichNeedsItsOwnHandlerBecauseImTooCheapAndStupidToBuyProperGamepad();
}
float hatX = 0.0f, hatY = 0.0f;
public void processGenericEvent(final MotionEvent event)
{
// Joysticks are supported since Honeycomb, but I don't care about it, because very little devices have it
if( (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK )
{
// event.getAxisValue(AXIS_HAT_X) and event.getAxisValue(AXIS_HAT_Y) are joystick arrow keys, they also send keyboard events
DemoGLSurfaceView.nativeGamepadAnalogJoystickInput(
event.getAxisValue(MotionEvent.AXIS_X), event.getAxisValue(MotionEvent.AXIS_Y),
event.getAxisValue(MotionEvent.AXIS_RX), event.getAxisValue(MotionEvent.AXIS_RZ),
0, 0);
if( event.getAxisValue(MotionEvent.AXIS_HAT_X) != hatX )
{
hatX = event.getAxisValue(MotionEvent.AXIS_HAT_X);
if( hatX == 0.0f )
{
DemoGLSurfaceView.nativeKey(KeyEvent.KEYCODE_DPAD_LEFT, 0);
DemoGLSurfaceView.nativeKey(KeyEvent.KEYCODE_DPAD_RIGHT, 0);
}
else
DemoGLSurfaceView.nativeKey(hatX < 0.0f ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT, 1);
}
if( event.getAxisValue(MotionEvent.AXIS_HAT_Y) != hatY )
{
hatY = event.getAxisValue(MotionEvent.AXIS_HAT_Y);
if( hatY == 0.0f )
{
DemoGLSurfaceView.nativeKey(KeyEvent.KEYCODE_DPAD_UP, 0);
DemoGLSurfaceView.nativeKey(KeyEvent.KEYCODE_DPAD_DOWN, 0);
}
else
DemoGLSurfaceView.nativeKey(hatY < 0.0f ? KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN, 1);
}
return;
}
super.processGenericEvent(event);
}
public boolean detect()
{
int[] devIds = InputDevice.getDeviceIds();
for( int id : devIds )
{
InputDevice device = InputDevice.getDevice(id);
if( device == null )
continue;
System.out.println("libSDL: input device ID " + id + " type " + device.getSources() + " name " + device.getName() );
if( (device.getSources() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD &&
(device.getSources() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK &&
device.getName().indexOf("DragonRise Inc") == 0 )
{
System.out.println("libSDL: Detected crappy DragonRise gamepad, enabling special hack for it. Please press button labeled 'Analog', otherwise it won't work, because it's cheap and crappy");
return true;
}
}
return false;
}
}
}
class DemoRenderer extends GLSurfaceView_SDL.Renderer
{
public DemoRenderer(MainActivity _context)
{
context = _context;
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceCreated(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
mGlSurfaceCreated = true;
mGl = gl;
if( ! mPaused && ! mFirstTimeStart )
nativeGlContextRecreated();
mFirstTimeStart = false;
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceChanged(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart + " w " + w + " h " + h);
if( w < h && Globals.HorizontalOrientation )
{
// Sometimes when Android awakes from lockscreen, portrait orientation is kept
int x = w;
w = h;
h = x;
}
mWidth = w;
mHeight = h;
mGl = gl;
nativeResize(w, h, Globals.KeepAspectRatio ? 1 : 0);
}
public void onSurfaceDestroyed() {
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceDestroyed(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
mGlSurfaceCreated = false;
mGlContextLost = true;
nativeGlContextLost();
};
public void onDrawFrame(GL10 gl) {
mGl = gl;
DrawLogo(mGl);
SwapBuffers();
nativeInitJavaCallbacks();
// Make main thread priority lower so audio thread won't get underrun
// Thread.currentThread().setPriority((Thread.currentThread().getPriority() + Thread.MIN_PRIORITY)/2);
mGlContextLost = false;
if(Globals.CompatibilityHacksStaticInit)
MainActivity.LoadApplicationLibrary(context);
Settings.Apply(context);
accelerometer = new AccelerometerReader(context);
// Tweak video thread priority, if user selected big audio buffer
if(Globals.AudioBufferConfig >= 2)
Thread.currentThread().setPriority( (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2 ); // Lower than normal
// Calls main() and never returns, hehe - we'll call eglSwapBuffers() from native code
nativeInit( Globals.DataDir,
Globals.CommandLine,
( (Globals.SwVideoMode && Globals.MultiThreadedVideo) || Globals.CompatibilityHacksVideo ) ? 1 : 0,
android.os.Debug.isDebuggerConnected() ? 1 : 0 );
System.exit(0); // The main() returns here - I don't bother with deinit stuff, just terminate process
}
public int swapBuffers() // Called from native code
{
if( ! super.SwapBuffers() && Globals.NonBlockingSwapBuffers )
{
if(mRatelimitTouchEvents)
{
synchronized(this)
{
this.notify();
}
}
return 0;
}
if(mGlContextLost) {
mGlContextLost = false;
Settings.SetupTouchscreenKeyboardGraphics(context); // Reload on-screen buttons graphics
DrawLogo(mGl);
super.SwapBuffers();
}
// Unblock event processing thread only after we've finished rendering
if(mRatelimitTouchEvents)
{
synchronized(this)
{
this.notify();
}
}
if( context.isScreenKeyboardShown() )
{
try {
Thread.sleep(50); // Give some time to the keyboard input thread
} catch(Exception e) { };
}
return 1;
}
public void showScreenKeyboardWithoutTextInputField() // Called from native code
{
class Callback implements Runnable
{
public MainActivity parent;
public void run()
{
parent.showScreenKeyboardWithoutTextInputField();
}
}
Callback cb = new Callback();
cb.parent = context;
context.runOnUiThread(cb);
}
public void showScreenKeyboard(final String oldText, int sendBackspace) // Called from native code
{
class Callback implements Runnable
{
public MainActivity parent;
public String oldText;
public boolean sendBackspace;
public void run()
{
parent.showScreenKeyboard(oldText, sendBackspace);
}
}
Callback cb = new Callback();
cb.parent = context;
cb.oldText = oldText;
cb.sendBackspace = (sendBackspace != 0);
context.runOnUiThread(cb);
}
public void hideScreenKeyboard() // Called from native code
{
class Callback implements Runnable
{
public MainActivity parent;
public void run()
{
parent.hideScreenKeyboard();
}
}
Callback cb = new Callback();
cb.parent = context;
context.runOnUiThread(cb);
}
public int isScreenKeyboardShown() // Called from native code
{
return context.isScreenKeyboardShown() ? 1 : 0;
}
public void setScreenKeyboardHintMessage(String s)
{
context.setScreenKeyboardHintMessage(s);
}
public void startAccelerometerGyroscope(int started)
{
accelerometer.openedBySDL = (started != 0);
if( accelerometer.openedBySDL && !mPaused )
accelerometer.start();
else
accelerometer.stop();
}
public void exitApp()
{
nativeDone();
}
public void getAdvertisementParams(int params[])
{
context.getAdvertisementParams(params);
}
public void setAdvertisementVisible(int visible)
{
context.setAdvertisementVisible(visible);
}
public void setAdvertisementPosition(int left, int top)
{
context.setAdvertisementPosition(left, top);
}
public void requestNewAdvertisement()
{
context.requestNewAdvertisement();
}
private int PowerOf2(int i)
{
int value = 1;
while (value < i)
value <<= 1;
return value;
}
public void DrawLogo(GL10 gl)
{
/*
// TODO: this not quite works, as it seems
BitmapDrawable bmp = null;
try
{
bmp = new BitmapDrawable(context.getAssets().open("logo.png"));
}
catch(Exception e)
{
bmp = new BitmapDrawable(context.getResources().openRawResource(R.drawable.publisherlogo));
}
int width = bmp.getBitmap().getWidth();
int height = bmp.getBitmap().getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * width * height);
//byteBuffer.order(ByteOrder.BIG_ENDIAN);
bmp.getBitmap().copyPixelsToBuffer(byteBuffer);
byteBuffer.position(0);
gl.glViewport(0, 0, mWidth, mHeight);
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1);
gl.glEnable(GL10.GL_TEXTURE_2D);
int textureName = -1;
int mTextureNameWorkspace[] = new int[1];
int mCropWorkspace[] = new int[4];
gl.glGenTextures(1, mTextureNameWorkspace, 0);
textureName = mTextureNameWorkspace[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glActiveTexture(textureName);
gl.glClientActiveTexture(textureName);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA,
PowerOf2(width), PowerOf2(height), 0,
GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0,
width, height,
GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, byteBuffer);
mCropWorkspace[0] = 0; // u
mCropWorkspace[1] = height; // v
mCropWorkspace[2] = width;
mCropWorkspace[3] = -height;
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);
((GL11Ext) gl).glDrawTexiOES(0, -mHeight, 0, mWidth, mHeight);
gl.glActiveTexture(0);
gl.glClientActiveTexture(0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
gl.glDeleteTextures(1, mTextureNameWorkspace, 0);
gl.glFlush();
*/
}
private native void nativeInitJavaCallbacks();
private native void nativeInit(String CurrentPath, String CommandLine, int multiThreadedVideo, int isDebuggerConnected);
private native void nativeResize(int w, int h, int keepAspectRatio);
private native void nativeDone();
private native void nativeGlContextLost();
public native void nativeGlContextRecreated();
public native void nativeGlContextLostAsyncEvent();
public static native void nativeTextInput( int ascii, int unicode );
public static native void nativeTextInputFinished();
private MainActivity context = null;
public AccelerometerReader accelerometer = null;
private GL10 mGl = null;
private EGL10 mEgl = null;
private EGLDisplay mEglDisplay = null;
private EGLSurface mEglSurface = null;
private EGLContext mEglContext = null;
private boolean mGlContextLost = false;
public boolean mGlSurfaceCreated = false;
public boolean mPaused = false;
private boolean mFirstTimeStart = true;
public int mWidth = 0;
public int mHeight = 0;
public static final boolean mRatelimitTouchEvents = true; //(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO);
}
class DemoGLSurfaceView extends GLSurfaceView_SDL {
public DemoGLSurfaceView(MainActivity context) {
super(context);
mParent = context;
touchInput = DifferentTouchInput.getInstance();
setEGLConfigChooser(Globals.VideoDepthBpp, Globals.NeedDepthBuffer, Globals.NeedStencilBuffer, Globals.NeedGles2);
mRenderer = new DemoRenderer(context);
setRenderer(mRenderer);
}
@Override
public boolean onTouchEvent(final MotionEvent event)
{
touchInput.process(event);
if( DemoRenderer.mRatelimitTouchEvents )
{
limitEventRate(event);
}
return true;
};
@Override
public boolean onGenericMotionEvent (final MotionEvent event)
{
touchInput.processGenericEvent(event);
if( DemoRenderer.mRatelimitTouchEvents )
{
limitEventRate(event);
}
return true;
}
public void limitEventRate(final MotionEvent event)
{
// Wait a bit, and try to synchronize to app framerate, or event thread will eat all CPU and we'll lose FPS
// With Froyo the rate of touch events seems to be limited by OS, but they are arriving faster then we're redrawing anyway
if((event.getAction() == MotionEvent.ACTION_MOVE ||
event.getAction() == MotionEvent.ACTION_HOVER_MOVE))
{
synchronized(mRenderer)
{
try
{
mRenderer.wait(300L); // And sometimes the app decides not to render at all, so this timeout should not be big.
} catch (InterruptedException e) { }
}
}
}
public void exitApp() {
mRenderer.exitApp();
};
@Override
public void onPause() {
if(mRenderer.mPaused)
return;
mRenderer.mPaused = true;
mRenderer.nativeGlContextLostAsyncEvent();
if( mRenderer.accelerometer != null ) // For some reason it crashes here often - are we getting this event before initialization?
mRenderer.accelerometer.stop();
super.onPause();
};
public boolean isPaused() {
return mRenderer.mPaused;
}
@Override
public void onResume() {
if(!mRenderer.mPaused)
return;
mRenderer.mPaused = false;
super.onResume();
Log.i("SDL", "libSDL: DemoGLSurfaceView.onResume(): mRenderer.mGlSurfaceCreated " + mRenderer.mGlSurfaceCreated + " mRenderer.mPaused " + mRenderer.mPaused);
if( mRenderer.mGlSurfaceCreated && ! mRenderer.mPaused || Globals.NonBlockingSwapBuffers )
mRenderer.nativeGlContextRecreated();
if( mRenderer.accelerometer != null && mRenderer.accelerometer.openedBySDL ) // For some reason it crashes here often - are we getting this event before initialization?
mRenderer.accelerometer.start();
};
// This seems like redundant code - it handled in MainActivity.java
@Override
public boolean onKeyDown(int keyCode, final KeyEvent event) {
//Log.i("SDL", "Got key down event, id " + keyCode + " meta " + event.getMetaState() + " event " + event.toString());
if( nativeKey( keyCode, 1 ) == 0 )
return super.onKeyDown(keyCode, event);
return true;
}
@Override
public boolean onKeyUp(int keyCode, final KeyEvent event) {
//Log.i("SDL", "Got key up event, id " + keyCode + " meta " + event.getMetaState());
if( nativeKey( keyCode, 0 ) == 0 )
return super.onKeyUp(keyCode, event);
return true;
}
DemoRenderer mRenderer;
MainActivity mParent;
DifferentTouchInput touchInput = null;
public static native void nativeMotionEvent( int x, int y, int action, int pointerId, int pressure, int radius );
public static native int nativeKey( int keyCode, int down );
public static native void nativeTouchpad( int x, int y, int down, int multitouch );
public static native void initJavaCallbacks();
public static native void nativeHardwareMouseDetected( int detected );
public static native void nativeMouseButtonsPressed( int buttonId, int pressedState );
public static native void nativeMouseWheel( int scrollX, int scrollY );
public static native void nativeGamepadAnalogJoystickInput( float stick1x, float stick1y, float stick2x, float stick2y, float rtrigger, float ltrigger );
}