84 changes: 84 additions & 0 deletions Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java
@@ -0,0 +1,84 @@
package org.dolphinemu.dolphinemu;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

public class GameListItem implements Comparable<GameListItem>{
private String name;
private String data;
private String path;
private Bitmap image;
public static native int[] GetBanner(String filename);
public static native String GetTitle(String filename);
static
{
try
{
System.loadLibrary("dolphin-emu-nogui");
}
catch (Exception ex)
{
Log.w("me", ex.toString());
}
}

public GameListItem(Context ctx, String n,String d,String p)
{
name = n;
data = d;
path = p;
File file = new File(path);
if (!file.isDirectory())
{
int[] Banner = GetBanner(path);
if (Banner[0] == 0)
{
try {
InputStream path = ctx.getAssets().open("NoBanner.png");
image = BitmapFactory.decodeStream(path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
else
image = Bitmap.createBitmap(Banner, 96, 32, Bitmap.Config.ARGB_8888);
name = GetTitle(path);
}
}

public String getName()
{
return name;
}

public String getData()
{
return data;
}

public String getPath()
{
return path;
}
public Bitmap getImage()
{
return image;
}

public int compareTo(GameListItem o)
{
if(this.name != null)
return this.name.toLowerCase().compareTo(o.getName().toLowerCase());
else
throw new IllegalArgumentException();
}
}

181 changes: 181 additions & 0 deletions Source/Android/src/org/dolphinemu/dolphinemu/GameListView.java
@@ -0,0 +1,181 @@
package org.dolphinemu.dolphinemu;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.simonvt.menudrawer.MenuDrawer;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class GameListView extends ListActivity {
private GameListAdapter adapter;
private static File currentDir = null;
private MenuDrawer mDrawer;

private SideMenuAdapter mAdapter;
private ListView mList;
private static GameListView me;
public static native String GetConfig(String Key, String Value, String Default);
public static native void SetConfig(String Key, String Value, String Default);

private void Fill(File f)
{
File[]dirs = f.listFiles();
this.setTitle("Game List");
List<GameListItem>dir = new ArrayList<GameListItem>();
List<GameListItem>fls = new ArrayList<GameListItem>();

try
{
for(File ff: dirs)
{
if (ff.getName().charAt(0) != '.')
if(!ff.isDirectory())
if (ff.getName().toLowerCase().contains(".gcm") ||
ff.getName().toLowerCase().contains(".iso") ||
ff.getName().toLowerCase().contains(".wbfs") ||
ff.getName().toLowerCase().contains(".gcz") ||
ff.getName().toLowerCase().contains(".dol") ||
ff.getName().toLowerCase().contains(".elf"))
fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath()));
}
}
catch(Exception e)
{
}

Collections.sort(dir);
Collections.sort(fls);
dir.addAll(fls);

adapter = new GameListAdapter(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);
GameListItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){
}
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 onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK)
{
String FileName = data.getStringExtra("Select");
Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show();
SetConfig("General", "GCMPathes", "1");
SetConfig("General", "GCMPaths0", FileName);

currentDir = new File(FileName);
Fill(currentDir);
}
}

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
me = this;

mDrawer = MenuDrawer.attach(this, MenuDrawer.MENU_DRAG_CONTENT);

String BrowseDir = GetConfig("General", "GCMPaths0", "");
if(currentDir == null)
currentDir = new File(BrowseDir);
Fill(currentDir);

List<SideMenuItem>dir = new ArrayList<SideMenuItem>();
dir.add(new SideMenuItem("Browse Folder", 0));

mList = new ListView(this);
mAdapter = new SideMenuAdapter(this,R.layout.sidemenu,dir);
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mItemClickListener);

mDrawer.setMenuView(mList);
}
private AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SideMenuItem o = mAdapter.getItem(position);

switch(o.getID())
{
case 0:
Toast.makeText(me, "Loading up the browser", Toast.LENGTH_SHORT).show();
Intent ListIntent = new Intent(me, FolderBrowser.class);
startActivityForResult(ListIntent, 1);
break;
default:
break;
}
mDrawer.closeMenu();
}
};
@Override
public void setContentView(int layoutResID) {
// This override is only needed when using MENU_DRAG_CONTENT.
mDrawer.setContentView(layoutResID);
onContentChanged();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawer.toggleMenu();
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onBackPressed() {
final int drawerState = mDrawer.getDrawerState();
if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) {
mDrawer.closeMenu();
return;
}

super.onBackPressed();
}
}
94 changes: 0 additions & 94 deletions Source/Android/src/org/dolphinemu/dolphinemu/NativeListView.java

This file was deleted.

38 changes: 0 additions & 38 deletions Source/Android/src/org/dolphinemu/dolphinemu/Option.java

This file was deleted.

49 changes: 49 additions & 0 deletions Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java
@@ -0,0 +1,49 @@
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 SideMenuAdapter extends ArrayAdapter<SideMenuItem>{

private Context c;
private int id;
private List<SideMenuItem>items;

public SideMenuAdapter(Context context, int textViewResourceId,
List<SideMenuItem> objects) {
super(context, textViewResourceId, objects);
c = context;
id = textViewResourceId;
items = objects;
}
public SideMenuItem 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 SideMenuItem o = items.get(position);
if (o != null) {
TextView t1 = (TextView) v.findViewById(R.id.TextView01);

if(t1!=null)
t1.setText(o.getName());
}
return v;
}



}

30 changes: 30 additions & 0 deletions Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java
@@ -0,0 +1,30 @@
package org.dolphinemu.dolphinemu;

public class SideMenuItem implements Comparable<SideMenuItem>{
private String m_name;
private int m_id;

public SideMenuItem(String n, int id)
{
m_name = n;
m_id = id;
}

public String getName()
{
return m_name;
}
public int getID()
{
return m_id;
}

public int compareTo(SideMenuItem o)
{
if(this.m_name != null)
return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase());
else
throw new IllegalArgumentException();
}
}

115 changes: 114 additions & 1 deletion Source/Core/DolphinWX/Src/MainAndroid.cpp
Expand Up @@ -35,6 +35,11 @@
#include "BootManager.h"
#include "OnScreenDisplay.h"

// Banner loading
#include "Filesystem.h"
#include "BannerLoader.h"
#include "VolumeCreator.h"

#include "Android/ButtonManager.h"

#include <jni.h>
Expand Down Expand Up @@ -140,6 +145,57 @@ void OSDCallbacks(u32 UserData)
}
}

#define DVD_BANNER_WIDTH 96
#define DVD_BANNER_HEIGHT 32
std::vector<std::string> m_volume_names;
std::vector<std::string> m_names;

bool LoadBanner(std::string filename, u32 *Banner)
{
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename);

if (pVolume != NULL)
{
bool bIsWad = false;
if (DiscIO::IsVolumeWadFile(pVolume))
bIsWad = true;

m_volume_names = pVolume->GetNames();

// check if we can get some info from the banner file too
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);

if (pFileSystem != NULL || bIsWad)
{
DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem, pVolume);

if (pBannerLoader != NULL)
if (pBannerLoader->IsValid())
{
m_names = pBannerLoader->GetNames();
if (pBannerLoader->GetBanner(Banner))
return true;
}
}
}

return false;
}
std::string GetName(std::string filename)
{
if (!m_names.empty())
return m_names[0];

if (!m_volume_names.empty())
return m_volume_names[0];
// No usable name, return filename (better than nothing)
std::string name;
SplitPath(filename, NULL, &name, NULL);

return name;
}


#ifdef __cplusplus
extern "C"
{
Expand All @@ -162,6 +218,63 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_DolphinEmulator_onTouchEve
ButtonManager::TouchEvent(Action, X, Y);
}


JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_GameListItem_GetBanner(JNIEnv *env, jobject obj, jstring jFile)
{
const char *File = env->GetStringUTFChars(jFile, NULL);
jintArray Banner = env->NewIntArray(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT);
u32 uBanner[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT];
if (LoadBanner(File, uBanner))
{
env->SetIntArrayRegion(Banner, 0, DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT, (jint*)uBanner);
}
env->ReleaseStringUTFChars(jFile, File);
return Banner;
}
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_GameListItem_GetTitle(JNIEnv *env, jobject obj, jstring jFile)
{
const char *File = env->GetStringUTFChars(jFile, NULL);
std::string Name = GetName(File);
m_names.clear();
m_volume_names.clear();

env->ReleaseStringUTFChars(jFile, File);
return env->NewStringUTF(Name.c_str());
}
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_GameListView_GetConfig(JNIEnv *env, jobject obj, jstring jKey, jstring jValue, jstring jDefault)
{
IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
const char *Key = env->GetStringUTFChars(jKey, NULL);
const char *Value = env->GetStringUTFChars(jValue, NULL);
const char *Default = env->GetStringUTFChars(jDefault, NULL);

std::string value;

ini.Get(Key, Value, &value, Default);

env->ReleaseStringUTFChars(jKey, Key);
env->ReleaseStringUTFChars(jValue, Value);
env->ReleaseStringUTFChars(jDefault, Default);

return env->NewStringUTF(value.c_str());
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_GameListView_SetConfig(JNIEnv *env, jobject obj, jstring jKey, jstring jValue, jstring jDefault)
{
IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
const char *Key = env->GetStringUTFChars(jKey, NULL);
const char *Value = env->GetStringUTFChars(jValue, NULL);
const char *Default = env->GetStringUTFChars(jDefault, NULL);

ini.Set(Key, Value, Default);
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));

env->ReleaseStringUTFChars(jKey, Key);
env->ReleaseStringUTFChars(jValue, Value);
env->ReleaseStringUTFChars(jDefault, Default);
}

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeGLSurfaceView_main(JNIEnv *env, jobject obj, jstring jFile, jobject _surf, jint _width, jint _height)
{
surf = ANativeWindow_fromSurface(env, _surf);
Expand All @@ -178,7 +291,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeGLSurfaceView_main(J
VideoBackend::PopulateList();
VideoBackend::ActivateBackend(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend);
WiimoteReal::LoadSettings();

const char *File = env->GetStringUTFChars(jFile, NULL);
// No use running the loop when booting fails
if ( BootManager::BootCore( File ) )
Expand Down