diff --git a/README.md b/README.md index 588100694..6ea9d7afc 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,15 @@ Let's try to keep everything under a single project :) To build for android -------------------- Tools required: -* Latest Android SDK and NDK -* Android 4.4 (API 19) or newer (http://developer.android.com/sdk/installing/adding-packages.html) +* Latest Android SDK + - http://developer.android.com/sdk/index.html +* NDK r8b or newer + - https://developer.android.com/tools/sdk/ndk/index.html + - If are not using r9c+, comment the "NDK_TOOLCHAIN_VERSION := 4.8" in shell/android/jni/Application.mk and shell/android/xperia/jni/Application.mk +* Android 4.4 (API 19) & Android 2.3.1 (API 9) + - http://developer.android.com/sdk/installing/adding-packages.html * Ant + - http://ant.apache.org/ From project root directory: ``` diff --git a/shell/android/jni/Application.mk b/shell/android/jni/Application.mk index 8d449d9be..4d14fad8c 100644 --- a/shell/android/jni/Application.mk +++ b/shell/android/jni/Application.mk @@ -1,5 +1,5 @@ APP_STL := stlport_static #APP_ABI := armeabi-v7a x86 APP_ABI := armeabi-v7a -APP_PLATFORM := android-18 +APP_PLATFORM := android-19 NDK_TOOLCHAIN_VERSION := 4.8 \ No newline at end of file diff --git a/shell/android/res/values/donottranslate.xml b/shell/android/res/values/donottranslate.xml index 1af369859..217d3e95f 100644 --- a/shell/android/res/values/donottranslate.xml +++ b/shell/android/res/values/donottranslate.xml @@ -7,6 +7,8 @@ https://github.com/reicast/reicast-emulator/issues/ http://twisted.dyndns.tv:3194/ReicastBot/report/submit.php + + 16 24 diff --git a/shell/android/res/values/strings.xml b/shell/android/res/values/strings.xml index ce14a1565..72cb6e40f 100644 --- a/shell/android/res/values/strings.xml +++ b/shell/android/res/values/strings.xml @@ -6,11 +6,15 @@ Default System Path Storage Path (location of .gdi, .chd or .cdi images) Default Game Storage + Please configure a home directory + Please configure a games directory + Unsupported Kernel Version! Boot Dreamcast Bios BIOS Missing. The Dreamcast BIOS is required for this emulator to work. Place the BIOS file in %1$s/data/dc_boot.bin Flash Missing. The Dreamcast Flash is required for this emulator to work. Place the Flash file in %1$s/data/dc_flash.bin You have to provide the BIOS + The data folder is assumed BOOT BIOS SELECT CURRENT FOLDER diff --git a/shell/android/src/com/reicast/emulator/FileBrowser.java b/shell/android/src/com/reicast/emulator/FileBrowser.java index 7eb7336b2..08af1323c 100644 --- a/shell/android/src/com/reicast/emulator/FileBrowser.java +++ b/shell/android/src/com/reicast/emulator/FileBrowser.java @@ -148,7 +148,7 @@ public class FileBrowser extends Fragment { File home = new File(home_directory); if (!home.exists() || !home.isDirectory()) { - Toast.makeText(getActivity(), "Please configure a home directory", + Toast.makeText(getActivity(), R.string.config_home, Toast.LENGTH_LONG).show(); } @@ -217,7 +217,7 @@ public class FileBrowser extends Fragment { createListItem(list, games.get(i)); } } else { - Toast.makeText(parentActivity, "Please configure a games directory", + Toast.makeText(parentActivity, R.string.config_game, Toast.LENGTH_LONG).show(); } list.invalidate(); diff --git a/shell/android/src/com/reicast/emulator/GL2JNIActivity.java b/shell/android/src/com/reicast/emulator/GL2JNIActivity.java index c8d4feb96..64b9b9395 100644 --- a/shell/android/src/com/reicast/emulator/GL2JNIActivity.java +++ b/shell/android/src/com/reicast/emulator/GL2JNIActivity.java @@ -23,7 +23,6 @@ import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.LinearLayout; import android.widget.PopupWindow; -import android.widget.Toast; import com.reicast.emulator.config.Config; import com.reicast.emulator.emu.GL2JNIView; diff --git a/shell/android/src/com/reicast/emulator/GL2JNINative.java b/shell/android/src/com/reicast/emulator/GL2JNINative.java index 342edbb62..fc4750536 100644 --- a/shell/android/src/com/reicast/emulator/GL2JNINative.java +++ b/shell/android/src/com/reicast/emulator/GL2JNINative.java @@ -23,7 +23,6 @@ import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.LinearLayout; import android.widget.PopupWindow; -import android.widget.Toast; import com.reicast.emulator.config.Config; import com.reicast.emulator.emu.GL2JNIView; diff --git a/shell/android/src/com/reicast/emulator/MainActivity.java b/shell/android/src/com/reicast/emulator/MainActivity.java index 6064680be..6a71452e9 100644 --- a/shell/android/src/com/reicast/emulator/MainActivity.java +++ b/shell/android/src/com/reicast/emulator/MainActivity.java @@ -4,7 +4,6 @@ import java.io.File; import java.lang.Thread.UncaughtExceptionHandler; import java.util.List; -import tv.ouya.console.api.OuyaFacade; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; @@ -27,6 +26,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.TextView; +import android.widget.Toast; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenListener; @@ -347,6 +347,10 @@ public class MainActivity extends SlidingFragmentActivity implements } public void onGameSelected(Uri uri) { + if (GenerateLogs.readOutput("uname -a").equals(getString(R.string.error_kernel))) { + Toast.makeText(MainActivity.this, R.string.unsupported, + Toast.LENGTH_SHORT).show(); + } String msg = null; if (!isBiosExisting()) msg = getString(R.string.missing_bios, home_directory); @@ -362,51 +366,51 @@ public class MainActivity extends SlidingFragmentActivity implements // set dialog message alertDialogBuilder - .setMessage(msg) - .setCancelable(false) - .setPositiveButton("Dismiss", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int id) { - // if this button is clicked, close - // current activity - // MainActivity.this.finish(); - } - }) - .setNegativeButton("Options", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int id) { - FileBrowser firstFragment = new FileBrowser(); - Bundle args = new Bundle(); - // args.putBoolean("ImgBrowse", false); - // specify ImgBrowse option. true = images, - // false = folders only - args.putString("browse_entry", - sdcard.toString()); - // specify a path for selecting folder - // options - args.putBoolean("games_entry", false); - // selecting a BIOS folder, so this is not - // games + .setMessage(msg) + .setCancelable(false) + .setPositiveButton("Dismiss", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int id) { + // if this button is clicked, close + // current activity + // MainActivity.this.finish(); + } + }) + .setNegativeButton("Options", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int id) { + FileBrowser firstFragment = new FileBrowser(); + Bundle args = new Bundle(); + // args.putBoolean("ImgBrowse", false); + // specify ImgBrowse option. true = images, + // false = folders only + args.putString("browse_entry", + sdcard.toString()); + // specify a path for selecting folder + // options + args.putBoolean("games_entry", false); + // selecting a BIOS folder, so this is not + // games - firstFragment.setArguments(args); - // In case this activity was started with - // special instructions from - // an Intent, pass the Intent's extras to - // the fragment as arguments - // firstFragment.setArguments(getIntent().getExtras()); + firstFragment.setArguments(args); + // In case this activity was started with + // special instructions from + // an Intent, pass the Intent's extras to + // the fragment as arguments + // firstFragment.setArguments(getIntent().getExtras()); - // Add the fragment to the - // 'fragment_container' FrameLayout - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.fragment_container, - firstFragment, - "MAIN_BROWSER") - .addToBackStack(null).commit(); - } - }); + // Add the fragment to the + // 'fragment_container' FrameLayout + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, + firstFragment, + "MAIN_BROWSER") + .addToBackStack(null).commit(); + } + }); // create alert dialog AlertDialog alertDialog = alertDialogBuilder.create(); @@ -416,7 +420,7 @@ public class MainActivity extends SlidingFragmentActivity implements } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && !Config.nonative) { startActivity(new Intent(Intent.ACTION_VIEW, uri, getBaseContext(), - GL2JNINative.class)); + GL2JNINative.class)); } else { startActivity(new Intent(Intent.ACTION_VIEW, uri, getBaseContext(), GL2JNIActivity.class)); diff --git a/shell/android/src/com/reicast/emulator/config/EditVJoyActivity.java b/shell/android/src/com/reicast/emulator/config/EditVJoyActivity.java index b27fe0902..87ca455e4 100644 --- a/shell/android/src/com/reicast/emulator/config/EditVJoyActivity.java +++ b/shell/android/src/com/reicast/emulator/config/EditVJoyActivity.java @@ -18,7 +18,6 @@ import android.widget.ImageButton; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.PopupWindow; -import android.widget.Toast; import com.reicast.emulator.MainActivity; import com.reicast.emulator.R; @@ -70,9 +69,6 @@ public class EditVJoyActivity extends Activity { vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext()); JNIdc.show_osd(); - - Toast.makeText(getApplicationContext(), - "Press the back button for a menu", Toast.LENGTH_SHORT).show(); } @Override diff --git a/shell/android/src/com/reicast/emulator/config/InputFragment.java b/shell/android/src/com/reicast/emulator/config/InputFragment.java index 89526ac54..3b91eccdb 100644 --- a/shell/android/src/com/reicast/emulator/config/InputFragment.java +++ b/shell/android/src/com/reicast/emulator/config/InputFragment.java @@ -416,8 +416,7 @@ public class InputFragment extends Fragment { || descriptor.equals(deviceDescriptorPlayer2) || descriptor.equals(deviceDescriptorPlayer3) || descriptor.equals(deviceDescriptorPlayer4)) { - Toast.makeText(parentActivity, - getString(R.string.controller_already_in_use), + Toast.makeText(parentActivity, R.string.controller_already_in_use, Toast.LENGTH_SHORT).show(); return true; } diff --git a/shell/android/src/com/reicast/emulator/config/OptionsFragment.java b/shell/android/src/com/reicast/emulator/config/OptionsFragment.java index 5b9f0a141..0b1d752fa 100644 --- a/shell/android/src/com/reicast/emulator/config/OptionsFragment.java +++ b/shell/android/src/com/reicast/emulator/config/OptionsFragment.java @@ -15,6 +15,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; +import android.widget.Toast; import com.reicast.emulator.R; @@ -86,6 +87,11 @@ public class OptionsFragment extends Fragment { public void afterTextChanged(Editable s) { if (editBrowse.getText() != null) { home_directory = editBrowse.getText().toString(); + if (home_directory.endsWith("/data")) { + home_directory.replace("/data", ""); + Toast.makeText(parentActivity, R.string.data_folder, + Toast.LENGTH_SHORT).show(); + } mPrefs.edit().putString("home_directory", home_directory) .commit(); } diff --git a/shell/android/src/com/reicast/emulator/periph/MOGAInput.java b/shell/android/src/com/reicast/emulator/periph/MOGAInput.java index 7d067c4de..ecd9659f5 100644 --- a/shell/android/src/com/reicast/emulator/periph/MOGAInput.java +++ b/shell/android/src/com/reicast/emulator/periph/MOGAInput.java @@ -3,8 +3,11 @@ package com.reicast.emulator.periph; /******************************************************************************/ +import java.util.Arrays; + import android.app.Activity; import android.content.SharedPreferences; +import android.os.Build; import android.os.Handler; import android.preference.PreferenceManager; import android.widget.Toast; @@ -137,46 +140,64 @@ public class MOGAInput // Handled by the primary controller interface } - public void onStateEvent(StateEvent event) - { - Integer playerNum = pad.deviceDescriptor_PlayerNum.get(pad.deviceId_deviceDescriptor.get(event.getControllerId())); + private void getCompatibilityMap(int playerNum, String id) { + pad.name[playerNum] = prefs.getInt("controller" + id, -1); + if (pad.name[playerNum] != -1) { + pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs); + } + } - if (playerNum == null) - return; + private void initJoyStickLayout(int playerNum) { + pad.globalLS_X[playerNum] = pad.previousLS_X[playerNum] = 0.0f; + pad.globalLS_Y[playerNum] = pad.previousLS_Y[playerNum] = 0.0f; + } - if(playerNum == 0) - JNIdc.hide_osd(); - + private void notifyMogaConnected(final String notify, int playerNum) { String id = pad.portId[playerNum]; pad.custom[playerNum] = prefs.getBoolean("modified_key_layout" + id, false); + pad.compat[playerNum] = prefs.getBoolean("controller_compat" + id, false); + pad.joystick[playerNum] = prefs.getBoolean("separate_joystick" + id, false); + pad.isActiveMoga[playerNum] = true; + if (pad.compat[playerNum]) { + getCompatibilityMap(playerNum, id); + } else if (pad.custom[playerNum]) { + pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs); + } else { + pad.map[playerNum] = pad.getMogaController(); + } + initJoyStickLayout(playerNum); + handler.post(new Runnable() { + public void run() { + Toast.makeText(act.getApplicationContext(), notify, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void onStateEvent(StateEvent event) + { + Integer playerNum = Arrays.asList(pad.name).indexOf(event.getControllerId()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && playerNum == -1) { + playerNum = pad.deviceDescriptor_PlayerNum + .get(pad.deviceId_deviceDescriptor.get(event.getControllerId())); + } else { + playerNum = -1; + } + + if (playerNum == null || playerNum == -1) { + return; + } if (event.getState() == StateEvent.STATE_CONNECTION && event.getAction() == ACTION_CONNECTED) { int mControllerVersion = mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION); if (mControllerVersion == Controller.ACTION_VERSION_MOGAPRO) { - pad.isActiveMoga[playerNum] = true; pad.isMogaPro[playerNum] = true; - if (pad.custom[playerNum]) { - pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs); - } else { - pad.map[playerNum] = pad.getMogaController(); - } notify = act.getApplicationContext().getString(R.string.moga_pro_connect); } else if (mControllerVersion == Controller.ACTION_VERSION_MOGA) { - pad.isActiveMoga[playerNum] = true; pad.isMogaPro[playerNum] = false; - if (pad.custom[playerNum]) { - pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs); - } else { - pad.map[playerNum] = pad.getMogaController(); - } notify = act.getApplicationContext().getString(R.string.moga_connect); } if (notify != null && !notify.equals(null)) { - handler.post(new Runnable() { - public void run() { - Toast.makeText(act.getApplicationContext(), notify, Toast.LENGTH_SHORT).show(); - } - }); + notifyMogaConnected(notify, playerNum); } } }