diff options
Diffstat (limited to 'Source/Android/src')
8 files changed, 614 insertions, 0 deletions
diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/Button.java b/Source/Android/src/org/dolphinemu/dolphinemu/Button.java new file mode 100644 index 0000000000..629e572d83 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/Button.java @@ -0,0 +1,33 @@ +package org.dolphinemu.dolphinemu; + +public class Button { + private String ButtonID; + private float _x; + private float _y; + private float _ex; + private float _ey; + public Button(String Button, float[] Coords) + { + ButtonID = Button; + _x = Coords[0]; + _y = Coords[1]; + _ex = Coords[4]; + _ey = Coords[5]; + } + public float X() + { + return _x; + } + public float Y() + { + return _y; + } + public float EX() + { + return _ex; + } + public float EY() + { + return _ey; + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/ButtonManager.java b/Source/Android/src/org/dolphinemu/dolphinemu/ButtonManager.java new file mode 100644 index 0000000000..ee7a8f79d0 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/ButtonManager.java @@ -0,0 +1,43 @@ +package org.dolphinemu.dolphinemu; + +public class ButtonManager { + + private final int NUMBUTTONS = 15; + + Button[] Buttons; + float[][] ButtonCoords = + { // X, Y, X, EY, EX, EY, EX, Y + {0.75f, -1.0f, 0.75f, -0.75f, 1.0f, -0.75f, 1.0f, -1.0f}, + {0.50f, -1.0f, 0.50f, -0.75f, 0.75f, -0.75f, 0.75f, -1.0f}, + }; + public ButtonManager() + { + Buttons = new Button[NUMBUTTONS]; + + Buttons[0] = new Button("A", ButtonCoords[0]); + Buttons[1] = new Button("B", ButtonCoords[1]); + + } + Button GetButton(int ID) + { + return Buttons[ID]; + } + float[][] GetButtonCoords() + { + return ButtonCoords; + } + public int ButtonPressed(int action, float x, float y) + { + for (int a = 0; a < 2; ++a) + { + if (x >= Buttons[a].X() && + x <= Buttons[a].EX() && + -y >= Buttons[a].Y() && + -y <= Buttons[a].EY()) + { + return a; + } + } + return -1; + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java new file mode 100644 index 0000000000..f95195b53e --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -0,0 +1,124 @@ +package org.dolphinemu.dolphinemu; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.MotionEvent; +import android.view.WindowManager; + +public class DolphinEmulator<MainActivity> extends Activity { + + static private NativeGLSurfaceView GLview = null; + static private NativeRenderer Renderer = null; + static private boolean Running = false; + + private float screenWidth; + private float screenHeight; + + public static native void SetKey(int Value, int Key); + + static + { + try + { + System.loadLibrary("dolphin-emu-nogui"); + } + catch (Exception ex) + { + Log.w("me", ex.toString()); + } + } + @Override + public void onStop() + { + super.onStop(); + if (Running) + Renderer.StopEmulation(); + } + @Override + public void onPause() + { + super.onPause(); + if (Running) + Renderer.PauseEmulation(); + } + @Override + public void onResume() + { + super.onResume(); + if (Running) + Renderer.UnPauseEmulation(); + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (savedInstanceState == null) + { + Intent ListIntent = new Intent(this, NativeListView.class); + startActivityForResult(ListIntent, 1); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) + { + super.onActivityResult(requestCode, resultCode, data); + + if (resultCode == Activity.RESULT_OK) + { + DisplayMetrics displayMetrics = new DisplayMetrics(); + WindowManager wm = (WindowManager) getApplicationContext().getSystemService(getApplicationContext().WINDOW_SERVICE); // the results will be higher than using the activity context object or the getWindowManager() shortcut + wm.getDefaultDisplay().getMetrics(displayMetrics); + screenWidth = displayMetrics.widthPixels; + screenHeight = displayMetrics.heightPixels; + + + String FileName = data.getStringExtra("Select"); + Renderer = new NativeRenderer(); + Renderer.setContext(getApplicationContext()); + + GLview = new NativeGLSurfaceView(this); + GLview.setEGLContextClientVersion(2); + GLview.setRenderer(Renderer); + + GLview.SetFileName(FileName); + setContentView(GLview); + Running = true; + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) + { + float X, Y; + int Action; + X = event.getX(); + Y = event.getY(); + Action = event.getActionMasked(); + + int Button = Renderer.ButtonPressed(Action, ((X / screenWidth) * 2.0f) - 1.0f, ((Y / screenHeight) * 2.0f) - 1.0f); + + if (Button != -1) + SetKey(Action, Button); + + return false; + } + + public boolean overrideKeys() + { + return false; + } + +}
\ No newline at end of file diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FileArrayAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/FileArrayAdapter.java new file mode 100644 index 0000000000..b49149a36c --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/FileArrayAdapter.java @@ -0,0 +1,53 @@ +package org.dolphinemu.dolphinemu; + +import java.util.List; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +public class FileArrayAdapter extends ArrayAdapter<Option>{ + + private Context c; + private int id; + private List<Option>items; + + public FileArrayAdapter(Context context, int textViewResourceId, + List<Option> objects) { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + public Option getItem(int i) + { + return items.get(i); + } + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + } + final Option o = items.get(position); + if (o != null) { + TextView t1 = (TextView) v.findViewById(R.id.TextView01); + TextView t2 = (TextView) v.findViewById(R.id.TextView02); + + if(t1!=null) + t1.setText(o.getName()); + if(t2!=null) + t2.setText(o.getData()); + + } + return v; + } + + + +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java new file mode 100644 index 0000000000..0babd5b919 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java @@ -0,0 +1,61 @@ +package org.dolphinemu.dolphinemu; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; + +public class NativeGLSurfaceView extends GLSurfaceView { + static private String FileName; + static private Thread myRun; + static private boolean Running = false; + static private boolean Created = false; + + public static native void main(String File, Surface surf); + + static + { + try + { + System.loadLibrary("dolphin-emu-nogui"); + } + catch (Exception ex) + { + Log.w("me", ex.toString()); + } + } + + + public NativeGLSurfaceView(Context context) { + super(context); + if (!Created) + { + myRun = new Thread() + { + @Override + public void run() { + main(FileName, getHolder().getSurface()); + } + }; + Created = true; + } + } + + public void surfaceCreated(SurfaceHolder holder) + { + super.surfaceCreated(holder); + if (!Running) + { + myRun.start(); + Running = true; + } + } + + public void SetFileName(String file) + { + FileName = file; + } + + +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeListView.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeListView.java new file mode 100644 index 0000000000..0b30cda639 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeListView.java @@ -0,0 +1,94 @@ +package org.dolphinemu.dolphinemu; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import android.app.Activity; +import android.app.ListActivity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.view.View; +import android.widget.ListView; +import android.widget.Toast; + +public class NativeListView extends ListActivity { + private FileArrayAdapter adapter; + static private File currentDir = null; + + private void Fill(File f) + { + File[]dirs = f.listFiles(); + this.setTitle("Current Dir: " + f.getName()); + List<Option>dir = new ArrayList<Option>(); + List<Option>fls = new ArrayList<Option>(); + + try + { + for(File ff: dirs) + { + if (ff.getName().charAt(0) != '.') + if(ff.isDirectory()) + dir.add(new Option(ff.getName(),"Folder",ff.getAbsolutePath())); + else + if (ff.getName().toLowerCase().indexOf(".gcm") >= 0 || + ff.getName().toLowerCase().indexOf(".iso") >= 0 || + ff.getName().toLowerCase().indexOf(".wbfs") >= 0 || + ff.getName().toLowerCase().indexOf(".gcz") >= 0 || + ff.getName().toLowerCase().indexOf(".dol") >= 0 || + ff.getName().toLowerCase().indexOf(".elf") >= 0) + fls.add(new Option(ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); + } + } + catch(Exception e) + { + } + + Collections.sort(dir); + Collections.sort(fls); + dir.addAll(fls); + + if(!f.getName().equalsIgnoreCase("sdcard")) + dir.add(0,new Option("..","Parent Directory",f.getParent())); + adapter = new FileArrayAdapter(this,R.layout.main,dir); + this.setListAdapter(adapter); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + // TODO Auto-generated method stub + super.onListItemClick(l, v, position, id); + Option o = adapter.getItem(position); + if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){ + currentDir = new File(o.getPath()); + Fill(currentDir); + } + else + { + onFileClick(o.getPath()); + } + } + + private void onFileClick(String o) + { + Toast.makeText(this, "File Clicked: " + o, Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(); + intent.putExtra("Select", o); + setResult(Activity.RESULT_OK, intent); + + this.finish(); + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + if(currentDir == null) + currentDir = new File(Environment.getExternalStorageDirectory().getPath()); + Fill(currentDir); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeRenderer.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeRenderer.java new file mode 100644 index 0000000000..f802cd2b55 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeRenderer.java @@ -0,0 +1,168 @@ +package org.dolphinemu.dolphinemu; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.opengl.GLES20; +import android.opengl.GLSurfaceView; +import android.opengl.GLUtils; +import android.util.Log; + +public class NativeRenderer implements GLSurfaceView.Renderer { + // Button Manager + private static ButtonManager Buttons; + + private static boolean Running = false; + + // Context + private static Context _gContext; + + // Native + public static native void DrawME(); + public static native void DrawButton(int GLTex, int ID); + public static native void SetButtonCoords(float[] Coords); + public static native void PrepareME(); + public static native void UnPauseEmulation(); + public static native void PauseEmulation(); + public static native void StopEmulation(); + + // Texture loading + private static int buttonA = -1; + private static int buttonB = -1; + + // Get a new texture id: + private static int newTextureID(GL10 gl) + { + int[] temp = new int[1]; + gl.glGenTextures(1, temp, 0); + return temp[0]; + } + + // Will load a texture out of a drawable resource file, and return an OpenGL texture ID: + private int loadTexture(GL10 gl, String resource) + { + // In which ID will we be storing this texture? + int id = newTextureID(gl); + + // Load up, and flip the texture: + InputStream File = null; + try { + File = _gContext.getAssets().open(resource); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + return 0; + } + + Bitmap bmp = BitmapFactory.decodeStream(File); + + gl.glBindTexture(GL10.GL_TEXTURE_2D, id); + + // Set all of our texture parameters: + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); + + // Generate, and load up all of the mipmaps: + for(int level=0, height = bmp.getHeight(), width = bmp.getWidth(); true; level++) + { + // Push the bitmap onto the GPU: + GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bmp, 0); + + // We need to stop when the texture is 1x1: + if(height==1 && width==1) break; + + // Resize, and let's go again: + width >>= 1; height >>= 1; + if(width<1) width = 1; + if(height<1) height = 1; + + Bitmap bmp2 = Bitmap.createScaledBitmap(bmp, width, height, true); + bmp.recycle(); + bmp = bmp2; + } + bmp.recycle(); + + return id; + } + + static + { + try + { + System.loadLibrary("dolphin-emu-nogui"); + } + catch (Exception ex) + { + Log.w("me", ex.toString()); + } + if (!Running) + Buttons = new ButtonManager(); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) + { + gl.glViewport(0, 0, width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) + { + if (!Running) + { + gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + gl.glEnable(GL10.GL_BLEND); + gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); + + buttonA = loadTexture(gl, "ButtonA.png"); + buttonB = loadTexture(gl, "ButtonB.png"); + SetButtonCoords(Flatten(Buttons.GetButtonCoords())); + PrepareME(); + Running = true; + } + } + public static float[] Flatten(float[][] data) { + + float[] list = new float[data.length * data[0].length]; + + for(int y = 0; y < data.length; ++y) + for (int x = 0; x < data[y].length; ++x) + list[y * data[0].length + x] = data[y][x]; + return list; + } + public void onDrawFrame(GL10 gl) + { + if (Running) + { + gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + DrawME(); + + // -1 is left + // -1 is bottom + + DrawButton(buttonA, 0); + DrawButton(buttonB, 1); + } + } + public void setContext(Context ctx) + { + _gContext = ctx; + } + public int ButtonPressed(int action, float x, float y) + { + return Buttons.ButtonPressed(action, x, y); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/Option.java b/Source/Android/src/org/dolphinemu/dolphinemu/Option.java new file mode 100644 index 0000000000..dba6dfd534 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/Option.java @@ -0,0 +1,38 @@ +package org.dolphinemu.dolphinemu; + +public class Option implements Comparable<Option>{ + private String name; + private String data; + private String path; + + public Option(String n,String d,String p) + { + name = n; + data = d; + path = p; + } + + public String getName() + { + return name; + } + + public String getData() + { + return data; + } + + public String getPath() + { + return path; + } + + public int compareTo(Option o) + { + if(this.name != null) + return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} + |
