diff --git a/.gitignore b/.gitignore
index 1d1690462..e4350c09b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.DS_Store
*.class
+*.orig
bin/
gen/
diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp
index bb294eba3..16e5a63fe 100644
--- a/core/hw/maple/maple_cfg.cpp
+++ b/core/hw/maple/maple_cfg.cpp
@@ -78,7 +78,7 @@ void mcfg_CreateDevices()
void mcfg_DestroyDevices()
{
- for (int i=0;i<3;i++)
- for (int j=0;j<5;j++)
+ for (int i=0;i<=3;i++)
+ for (int j=0;j<=5;j++)
delete MapleDevices[i][j];
-}
\ No newline at end of file
+}
diff --git a/shell/android/jni/src/Android.cpp b/shell/android/jni/src/Android.cpp
index 3337ac853..3abaff8b8 100644
--- a/shell/android/jni/src/Android.cpp
+++ b/shell/android/jni/src/Android.cpp
@@ -13,6 +13,7 @@
#include "profiler/profiler.h"
#include "cfg/cfg.h"
#include "rend/TexCache.h"
+#include "hw/maple/maple_devs.h"
#include "util.h"
@@ -29,9 +30,11 @@ extern "C"
JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_rendinit(JNIEnv *env,jobject obj,jint w,jint h) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_rendframe(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
- JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_kcode(JNIEnv * env, jobject obj,u32 k_code, u32 l_t, u32 r_t, u32 jx, u32 jy) __attribute__((visibility("default")));
+ JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_kcode(JNIEnv * env, jobject obj, jintArray k_code, jintArray l_t, jintArray r_t, jintArray jx, jintArray jy) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_vjoy(JNIEnv * env, jobject obj,u32 id,float x, float y, float w, float h) __attribute__((visibility("default")));
//JNIEXPORT jint JNICALL Java_com_reicast_emulator_JNIdc_play(JNIEnv *env,jobject obj,jshortArray result,jint size);
+
+ JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers) __attribute__((visibility("default")));
};
void egl_stealcntx();
@@ -39,6 +42,7 @@ void SetApplicationPath(wchar *path);
int dc_init(int argc,wchar* argv[]);
void dc_run();
void dc_term();
+void mcfg_Create(MapleDeviceType type,u32 bus,u32 port);
bool VramLockedWrite(u8* address);
@@ -51,6 +55,9 @@ extern int screen_width,screen_height;
static u64 tvs_base;
static char CurFileName[256];
+// Additonal controllers 2, 3 and 4 connected ?
+static bool add_controllers[3] = { false, true, false };
+
u16 kcode[4];
u32 vks[4];
s8 joyx[4],joyy[4];
@@ -84,6 +91,13 @@ static void *ThreadHandler(void *UserData)
strcat(Args[2],P);
}
+ // Add additonal controllers
+ for (int i = 0; i < 3; i++)
+ {
+ if (add_controllers[i])
+ mcfg_Create(MDT_SegaController,i+1,5);
+ }
+
// Run nullDC emulator
dc_init(Args[2]? 3:1,Args);
}
@@ -247,14 +261,28 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_rendframe(JNIEnv *env,job
while(!rend_single_frame()) ;
}
-JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_kcode(JNIEnv * env, jobject obj,u32 k_code, u32 l_t, u32 r_t, u32 jx, u32 jy)
+JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_kcode(JNIEnv * env, jobject obj, jintArray k_code, jintArray l_t, jintArray r_t, jintArray jx, jintArray jy)
{
- lt[0] = l_t;
- rt[0] = r_t;
- kcode[0] = k_code;
- kcode[3] = kcode[2] = kcode[1] = 0xFFFF;
- joyx[0]=jx;
- joyy[0]=jy;
+ jint *k_code_body = env->GetIntArrayElements(k_code, 0);
+ jint *l_t_body = env->GetIntArrayElements(l_t, 0);
+ jint *r_t_body = env->GetIntArrayElements(r_t, 0);
+ jint *jx_body = env->GetIntArrayElements(jx, 0);
+ jint *jy_body = env->GetIntArrayElements(jy, 0);
+
+ for(int i = 0; i < 4; i++)
+ {
+ kcode[i] = k_code_body[i];
+ lt[i] = l_t_body[i];
+ rt[i] = r_t_body[i];
+ joyx[i] = jx_body[i];
+ joyy[i] = jy_body[i];
+ }
+
+ env->ReleaseIntArrayElements(k_code, k_code_body, 0);
+ env->ReleaseIntArrayElements(l_t, l_t_body, 0);
+ env->ReleaseIntArrayElements(r_t, r_t_body, 0);
+ env->ReleaseIntArrayElements(jx, jx_body, 0);
+ env->ReleaseIntArrayElements(jy, jy_body, 0);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_rendinit(JNIEnv * env, jobject obj, jint w,jint h)
@@ -283,6 +311,13 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_vjoy(JNIEnv * env, jobjec
}
}
+JNIEXPORT void JNICALL Java_com_reicast_emulator_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers)
+{
+ jboolean *controllers_body = env->GetBooleanArrayElements(controllers, 0);
+ memcpy(add_controllers, controllers_body, 3);
+ env->ReleaseBooleanArrayElements(controllers, controllers_body, 0);
+}
+
u32 os_Push(void* frame, u32 amt, bool wait)
{
verify(amt==SAMPLE_COUNT);
@@ -294,4 +329,4 @@ u32 os_Push(void* frame, u32 amt, bool wait)
bool os_IsAudioBuffered()
{
return jenv->CallIntMethod(track,writemid,jsamples,-1)==0;
-}
\ No newline at end of file
+}
diff --git a/shell/android/res/layout/controllers_fragment.xml b/shell/android/res/layout/controllers_fragment.xml
new file mode 100644
index 000000000..d5a8c5c60
--- /dev/null
+++ b/shell/android/res/layout/controllers_fragment.xml
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/shell/android/res/values/strings.xml b/shell/android/res/values/strings.xml
index f00a78854..1132d1238 100644
--- a/shell/android/res/values/strings.xml
+++ b/shell/android/res/values/strings.xml
@@ -19,6 +19,17 @@
PVR Rendering (does nothing for now)
Available Dreamcast Games
+
+ Controller 1
+ Controller 2
+ Controller 3
+ Controller 4
+ None
+ Select Controller
+ Remove Controller
+ Select Controller
+ Press any button on the controller to assign to port
+ This controller is already in use!
- cdi
@@ -41,6 +52,7 @@
- Browser
- Settings
- Paths
+ - Controllers
- About
@@ -50,10 +62,11 @@
- @drawable/disk_unknown
- @drawable/config
- @drawable/open_folder
+ - @drawable/config
- @drawable/question
Item Icon
-
\ No newline at end of file
+
diff --git a/shell/android/src/com/reicast/emulator/ControllersFragment.java b/shell/android/src/com/reicast/emulator/ControllersFragment.java
new file mode 100644
index 000000000..7d34ab9cd
--- /dev/null
+++ b/shell/android/src/com/reicast/emulator/ControllersFragment.java
@@ -0,0 +1,268 @@
+package com.reicast.emulator;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public class ControllersFragment extends Fragment {
+
+ private Activity parentActivity;
+ private int listenForButton = 0;
+ private AlertDialog alertDialogSelectController;
+ private SharedPreferences mPrefs;
+
+ // Container Activity must implement this interface
+ public interface OnClickListener {
+ public void onMainBrowseSelected(String path_entry, boolean games);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.controllers_fragment, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ parentActivity = getActivity();
+
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(parentActivity);
+
+ Button buttonSelectControllerPlayer1 = (Button) getView()
+ .findViewById(R.id.buttonSelectControllerPlayer1);
+ buttonSelectControllerPlayer1.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ selectController(1);
+ }
+ });
+ Button buttonSelectControllerPlayer2 = (Button) getView()
+ .findViewById(R.id.buttonSelectControllerPlayer2);
+ buttonSelectControllerPlayer2.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ selectController(2);
+ }
+ });
+ Button buttonSelectControllerPlayer3 = (Button) getView()
+ .findViewById(R.id.buttonSelectControllerPlayer3);
+ buttonSelectControllerPlayer3.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ selectController(3);
+ }
+ });
+ Button buttonSelectControllerPlayer4 = (Button) getView()
+ .findViewById(R.id.buttonSelectControllerPlayer4);
+ buttonSelectControllerPlayer4.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ selectController(4);
+ }
+ });
+
+ Button buttonRemoveControllerPlayer1 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer1);
+ buttonRemoveControllerPlayer1.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ removeController(1);
+ }
+ });
+
+ Button buttonRemoveControllerPlayer2 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer2);
+ buttonRemoveControllerPlayer2.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ removeController(2);
+ }
+ });
+
+ Button buttonRemoveControllerPlayer3 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer3);
+ buttonRemoveControllerPlayer3.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ removeController(3);
+ }
+ });
+
+ Button buttonRemoveControllerPlayer4 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer4);
+ buttonRemoveControllerPlayer4.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ removeController(4);
+ }
+ });
+
+ updateControllers();
+ }
+
+ private void updateControllers() {
+ String deviceDescriptorPlayer1 = mPrefs.getString("device_descriptor_player_1", null);
+ String deviceDescriptorPlayer2 = mPrefs.getString("device_descriptor_player_2", null);
+ String deviceDescriptorPlayer3 = mPrefs.getString("device_descriptor_player_3", null);
+ String deviceDescriptorPlayer4 = mPrefs.getString("device_descriptor_player_4", null);
+
+ String labelPlayer1 = null, labelPlayer2 = null, labelPlayer3 = null, labelPlayer4 = null;
+
+ for (int devideId : InputDevice.getDeviceIds()) {
+ InputDevice dev = InputDevice.getDevice(devideId);
+ String descriptor = dev.getDescriptor();
+
+ if (descriptor != null) {
+ if (descriptor.equals(deviceDescriptorPlayer1))
+ labelPlayer1 = dev.getName() + " (" + descriptor + ")";
+ else if (descriptor.equals(deviceDescriptorPlayer2))
+ labelPlayer2 = dev.getName() + " (" + descriptor + ")";
+ else if (descriptor.equals(deviceDescriptorPlayer3))
+ labelPlayer3 = dev.getName() + " (" + descriptor + ")";
+ else if (descriptor.equals(deviceDescriptorPlayer4))
+ labelPlayer4 = dev.getName() + " (" + descriptor + ")";
+ }
+ }
+
+ TextView textViewDeviceDescriptorPlayer1 = (TextView) getView()
+ .findViewById(R.id.textViewDeviceDescriptorPlayer1);
+ Button buttonRemoveControllerPlayer1 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer1);
+ if (deviceDescriptorPlayer1 != null) {
+ textViewDeviceDescriptorPlayer1.setText(labelPlayer1);
+ buttonRemoveControllerPlayer1.setEnabled(true);
+ } else {
+ textViewDeviceDescriptorPlayer1.setText(getString(R.string.controller_none));
+ buttonRemoveControllerPlayer1.setEnabled(false);
+ }
+
+ TextView textViewDeviceDescriptorPlayer2 = (TextView) getView()
+ .findViewById(R.id.textViewDeviceDescriptorPlayer2);
+ Button buttonRemoveControllerPlayer2 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer2);
+ if (deviceDescriptorPlayer2 != null) {
+ textViewDeviceDescriptorPlayer2.setText(labelPlayer2);
+ buttonRemoveControllerPlayer2.setEnabled(true);
+ } else {
+ textViewDeviceDescriptorPlayer2.setText(getString(R.string.controller_none));
+ buttonRemoveControllerPlayer2.setEnabled(false);
+ }
+
+ TextView textViewDeviceDescriptorPlayer3 = (TextView) getView()
+ .findViewById(R.id.textViewDeviceDescriptorPlayer3);
+ Button buttonRemoveControllerPlayer3 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer3);
+ if (deviceDescriptorPlayer3 != null) {
+ textViewDeviceDescriptorPlayer3.setText(labelPlayer3);
+ buttonRemoveControllerPlayer3.setEnabled(true);
+ } else {
+ textViewDeviceDescriptorPlayer3.setText(getString(R.string.controller_none));
+ buttonRemoveControllerPlayer3.setEnabled(false);
+ }
+
+ TextView textViewDeviceDescriptorPlayer4 = (TextView) getView()
+ .findViewById(R.id.textViewDeviceDescriptorPlayer4);
+ Button buttonRemoveControllerPlayer4 = (Button) getView()
+ .findViewById(R.id.buttonRemoveControllerPlayer4);
+ if (deviceDescriptorPlayer4 != null) {
+ textViewDeviceDescriptorPlayer4.setText(labelPlayer4);
+ buttonRemoveControllerPlayer4.setEnabled(true);
+ } else {
+ textViewDeviceDescriptorPlayer4.setText(getString(R.string.controller_none));
+ buttonRemoveControllerPlayer4.setEnabled(false);
+ }
+ }
+
+ private void selectController(int playerNum) {
+ listenForButton = playerNum;
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
+ builder.setTitle(getString(R.string.select_controller_title));
+ builder.setMessage(getString(R.string.select_controller_message) + " " + String.valueOf(listenForButton) + ".");
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ listenForButton = 0;
+ dialog.dismiss();
+ }
+ });
+ builder.setOnKeyListener(new Dialog.OnKeyListener() {
+ //@Override
+ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+ mapDevice(event);
+ return true;
+ }
+ });
+ alertDialogSelectController = builder.create();
+ alertDialogSelectController.show();
+ }
+
+ private void mapDevice(KeyEvent event) {
+ String descriptor = InputDevice.getDevice(event.getDeviceId()).getDescriptor();
+
+ if (descriptor == null)
+ return;
+
+ String deviceDescriptorPlayer1 = mPrefs.getString("device_descriptor_player_1", null);
+ String deviceDescriptorPlayer2 = mPrefs.getString("device_descriptor_player_2", null);
+ String deviceDescriptorPlayer3 = mPrefs.getString("device_descriptor_player_3", null);
+ String deviceDescriptorPlayer4 = mPrefs.getString("device_descriptor_player_4", null);
+
+ if (descriptor.equals(deviceDescriptorPlayer1) || descriptor.equals(deviceDescriptorPlayer2) ||
+ descriptor.equals(deviceDescriptorPlayer3) || descriptor.equals(deviceDescriptorPlayer4)) {
+ Toast.makeText(parentActivity, getString(R.string.controller_already_in_use), Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ switch(listenForButton) {
+ case 0:
+ return;
+ case 1:
+ mPrefs.edit().putString("device_descriptor_player_1", descriptor).commit();
+ break;
+ case 2:
+ mPrefs.edit().putString("device_descriptor_player_2", descriptor).commit();
+ break;
+ case 3:
+ mPrefs.edit().putString("device_descriptor_player_3", descriptor).commit();
+ break;
+ case 4:
+ mPrefs.edit().putString("device_descriptor_player_4", descriptor).commit();
+ break;
+ }
+
+ Log.d("New controller for port " + String.valueOf(listenForButton) + ":", descriptor);
+
+ listenForButton = 0;
+ alertDialogSelectController.cancel();
+ updateControllers();
+ }
+
+ private void removeController(int playerNum) {
+ switch(playerNum) {
+ case 1:
+ mPrefs.edit().putString("device_descriptor_player_1", null).commit();
+ break;
+ case 2:
+ mPrefs.edit().putString("device_descriptor_player_2", null).commit();
+ break;
+ case 3:
+ mPrefs.edit().putString("device_descriptor_player_3", null).commit();
+ break;
+ case 4:
+ mPrefs.edit().putString("device_descriptor_player_4", null).commit();
+ break;
+ }
+
+ updateControllers();
+ }
+}
diff --git a/shell/android/src/com/reicast/emulator/GL2JNIActivity.java b/shell/android/src/com/reicast/emulator/GL2JNIActivity.java
index 515db92ed..b3364618c 100644
--- a/shell/android/src/com/reicast/emulator/GL2JNIActivity.java
+++ b/shell/android/src/com/reicast/emulator/GL2JNIActivity.java
@@ -1,6 +1,15 @@
package com.reicast.emulator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
import tv.ouya.console.api.OuyaController;
+
+import com.reicast.emulator.GL2JNIView.EmuThread;
+
+import android.content.SharedPreferences;
+import android.view.InputDevice;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
@@ -8,6 +17,7 @@ import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
@@ -29,10 +39,13 @@ public class GL2JNIActivity extends Activity {
PopupWindow popUp;
LayoutParams params;
MOGAInput moga = new MOGAInput();
- static boolean xbox = false, nVidia = false;
- float globalLS_X, globalLS_Y, previousLS_X, previousLS_Y;
+ static boolean[] xbox = { false, false, false, false }, nVidia = { false, false, false, false };
+ float[] globalLS_X = new float[4], globalLS_Y = new float[4], previousLS_X = new float[4], previousLS_Y = new float[4];
- int map[];
+ public static HashMap deviceId_deviceDescriptor = new HashMap();
+ public static HashMap deviceDescriptor_PlayerNum = new HashMap();
+
+ int map[][];
View addbut(int x, OnClickListener ocl) {
ImageButton but = new ImageButton(this);
@@ -129,24 +142,73 @@ public class GL2JNIActivity extends Activity {
// Call parent onCreate()
super.onCreate(icicle);
+ OuyaController.init(this);
+
+ map = new int[4][];
+
+ // Populate device descriptor-to-player-map from preferences
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ deviceDescriptor_PlayerNum.put(prefs.getString("device_descriptor_player_1", null), 0);
+ deviceDescriptor_PlayerNum.put(prefs.getString("device_descriptor_player_2", null), 1);
+ deviceDescriptor_PlayerNum.put(prefs.getString("device_descriptor_player_3", null), 2);
+ deviceDescriptor_PlayerNum.put(prefs.getString("device_descriptor_player_4", null), 3);
+
+ boolean controllerTwoConnected = false;
+ boolean controllerThreeConnected = false;
+ boolean controllerFourConnected = false;
+
+ for (HashMap.Entry e : deviceDescriptor_PlayerNum.entrySet()) {
+ String descriptor = e.getKey();
+ Integer playerNum = e.getValue();
+
+ switch (playerNum) {
+ case 1:
+ if (descriptor != null)
+ controllerTwoConnected = true;
+ break;
+ case 2:
+ if (descriptor != null)
+ controllerThreeConnected = true;
+ break;
+ case 3:
+ if (descriptor != null)
+ controllerFourConnected = true;
+ break;
+ }
+ }
+
+ JNIdc.initControllers(new boolean[] {controllerTwoConnected, controllerThreeConnected, controllerFourConnected});
int joys[] = InputDevice.getDeviceIds();
for (int i = 0; i < joys.length; i++) {
+ String descriptor = InputDevice.getDevice(joys[i]).getDescriptor();
Log.d("reidc", "InputDevice ID: " + joys[i]);
Log.d("reidc", "InputDevice Name: "
+ InputDevice.getDevice(joys[i]).getName());
+ Log.d("reidc", "InputDevice Descriptor: " + descriptor);
+ deviceId_deviceDescriptor.put(joys[i], descriptor);
+ }
+
+ for (int i = 0; i < joys.length; i++) {
+ Integer playerNum = deviceDescriptor_PlayerNum.get(deviceId_deviceDescriptor.get(joys[i]));
+
+ if (playerNum != null) {
+
if (InputDevice.getDevice(joys[i]).getName()
.equals("Sony PLAYSTATION(R)3 Controller")) {
- map = new int[] {
- OuyaController.BUTTON_Y, key_CONT_B,
- OuyaController.BUTTON_U, key_CONT_A,
- OuyaController.BUTTON_O, key_CONT_X,
- OuyaController.BUTTON_A, key_CONT_Y,
+ map[playerNum] = new int[] {
+ OuyaController.BUTTON_Y, key_CONT_Y,
+ OuyaController.BUTTON_U, key_CONT_X,
+ OuyaController.BUTTON_O, key_CONT_A,
+ OuyaController.BUTTON_A, key_CONT_B,
- OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
- OuyaController.BUTTON_DPAD_DOWN, key_CONT_DPAD_DOWN,
- OuyaController.BUTTON_DPAD_LEFT, key_CONT_DPAD_LEFT,
- OuyaController.BUTTON_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
+ OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
+ OuyaController.BUTTON_DPAD_DOWN,
+ key_CONT_DPAD_DOWN,
+ OuyaController.BUTTON_DPAD_LEFT,
+ key_CONT_DPAD_LEFT,
+ OuyaController.BUTTON_DPAD_RIGHT,
+ key_CONT_DPAD_RIGHT,
OuyaController.BUTTON_MENU, key_CONT_START,
OuyaController.BUTTON_R1, key_CONT_START
@@ -154,7 +216,7 @@ public class GL2JNIActivity extends Activity {
};
} else if (InputDevice.getDevice(joys[i]).getName()
.equals("Microsoft X-Box 360 pad")) {
- map = new int[] {
+ map[playerNum] = new int[] {
OuyaController.BUTTON_O, key_CONT_A,
OuyaController.BUTTON_A, key_CONT_B,
OuyaController.BUTTON_Y, key_CONT_Y,
@@ -170,10 +232,14 @@ public class GL2JNIActivity extends Activity {
OuyaController.BUTTON_MENU, key_CONT_START,
OuyaController.BUTTON_R1, key_CONT_START };
- xbox = true;
+
+ xbox[playerNum] = true;
+
+ globalLS_X[playerNum] = previousLS_X[playerNum] = 0.0f;
+ globalLS_Y[playerNum] = previousLS_Y[playerNum] = 0.0f;
} else if (InputDevice.getDevice(joys[i]).getName()
.contains("NVIDIA Corporation NVIDIA Controller")) {
- map = new int[] {
+ map[playerNum] = new int[] {
OuyaController.BUTTON_O, key_CONT_A,
OuyaController.BUTTON_A, key_CONT_B,
OuyaController.BUTTON_Y, key_CONT_Y,
@@ -189,9 +255,9 @@ public class GL2JNIActivity extends Activity {
OuyaController.BUTTON_MENU, key_CONT_START,
OuyaController.BUTTON_R1, key_CONT_START };
- nVidia = true;
+ nVidia[playerNum] = true;
} else if (!moga.isActive) { // Ouya controller
- map = new int[] {
+ map[playerNum] = new int[] {
OuyaController.BUTTON_O, key_CONT_A,
OuyaController.BUTTON_A, key_CONT_B,
OuyaController.BUTTON_Y, key_CONT_Y,
@@ -208,6 +274,7 @@ public class GL2JNIActivity extends Activity {
OuyaController.BUTTON_MENU, key_CONT_START,
OuyaController.BUTTON_R1, key_CONT_START };
}
+ }
}
// When viewing a resource, pass its URI to the native code for opening
@@ -228,9 +295,10 @@ public class GL2JNIActivity extends Activity {
// Log.w("INPUT", event.toString() + " " + event.getSource());
// Get all the axis for the KeyEvent
- if (nVidia) {
- JNIdc.hide_osd();
- }
+ Integer playerNum = deviceDescriptor_PlayerNum.get(deviceId_deviceDescriptor.get(event.getDeviceId()));
+
+ if (playerNum == null)
+ return false;
if (!moga.isActive) {
@@ -245,23 +313,24 @@ public class GL2JNIActivity extends Activity {
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
- if (xbox || nVidia) {
- previousLS_X = globalLS_X;
- previousLS_Y = globalLS_Y;
- globalLS_X = LS_X;
- globalLS_Y = LS_Y;
+ if (xbox[playerNum] || nVidia[playerNum]) {
+ previousLS_X[playerNum] = globalLS_X[playerNum];
+ previousLS_Y[playerNum] = globalLS_Y[playerNum];
+ globalLS_X[playerNum] = LS_X;
+ globalLS_Y[playerNum] = LS_Y;
}
- GL2JNIView.lt = (int) (L2 * 255);
- GL2JNIView.rt = (int) (R2 * 255);
+ GL2JNIView.lt[playerNum] = (int) (L2 * 255);
+ GL2JNIView.rt[playerNum] = (int) (R2 * 255);
- GL2JNIView.jx = (int) (LS_X * 126);
- GL2JNIView.jy = (int) (LS_Y * 126);
+ GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
+ GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
}
}
- if ((xbox || nVidia) && globalLS_X == previousLS_X && globalLS_Y == previousLS_Y)
+ if ((xbox[playerNum] || nVidia[playerNum]) && ((globalLS_X[playerNum] == previousLS_X[playerNum] && globalLS_Y[playerNum] == previousLS_Y[playerNum])
+ || (previousLS_X[playerNum] == 0.0f && previousLS_Y[playerNum] == 0.0f)))
// Only handle Left Stick on an Xbox 360 controller if there was some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return false;
@@ -313,16 +382,19 @@ public class GL2JNIActivity extends Activity {
* };
*/
- boolean handle_key(int kc, boolean down) {
+ boolean handle_key(Integer playerNum, int kc, boolean down) {
+ if (playerNum == null)
+ return false;
+
if (!moga.isActive) {
boolean rav = false;
- for (int i = 0; i < map.length; i += 2) {
- if (map[i + 0] == kc) {
+ for (int i = 0; i < map[playerNum].length; i += 2) {
+ if (map[playerNum][i + 0] == kc) {
if (down)
- GL2JNIView.kcode_raw &= ~map[i + 1];
+ GL2JNIView.kcode_raw[playerNum] &= ~map[playerNum][i + 1];
else
- GL2JNIView.kcode_raw |= map[i + 1];
+ GL2JNIView.kcode_raw[playerNum] |= map[playerNum][i + 1];
rav = true;
break;
@@ -337,12 +409,17 @@ public class GL2JNIActivity extends Activity {
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
- return handle_key(keyCode, false) || super.onKeyUp(keyCode, event);
+ Integer playerNum = deviceDescriptor_PlayerNum.get(deviceId_deviceDescriptor.get(event.getDeviceId()));
+
+ return handle_key(playerNum, keyCode, false) || super.onKeyUp(keyCode, event);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (handle_key(keyCode, true)) {
- JNIdc.hide_osd();
+ Integer playerNum = deviceDescriptor_PlayerNum.get(deviceId_deviceDescriptor.get(event.getDeviceId()));
+
+ if (handle_key(playerNum, keyCode, true)) {
+ if(playerNum == 0)
+ JNIdc.hide_osd();
return true;
}
diff --git a/shell/android/src/com/reicast/emulator/GL2JNIView.java b/shell/android/src/com/reicast/emulator/GL2JNIView.java
index b9a75cc63..0098e5d5f 100644
--- a/shell/android/src/com/reicast/emulator/GL2JNIView.java
+++ b/shell/android/src/com/reicast/emulator/GL2JNIView.java
@@ -120,7 +120,9 @@ class GL2JNIView extends GLSurfaceView
JNIdc.data(1, GL2JNIActivity.syms);
JNIdc.hide_osd();
- JNIdc.kcode(0xFFFF,0,0,128,128);
+ int[] kcode = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
+ int[] rt = { 0, 0, 0, 0 }, lt = { 0, 0, 0, 0 };
+ int[] jx = { 128, 128, 128, 128 }, jy = { 128, 128, 128, 128 };
JNIdc.init(fileName);
@@ -264,8 +266,8 @@ class GL2JNIView extends GLSurfaceView
}
*/
- static int kcode_raw = 0xFFFF;
- static int lt, rt, jx, jy;
+ static int[] kcode_raw = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
+ static int[] lt = new int[4], rt = new int[4], jx = new int[4], jy = new int[4];
@Override public boolean onTouchEvent(final MotionEvent event)
{
@@ -321,8 +323,8 @@ class GL2JNIView extends GLSurfaceView
anal_id=event.getPointerId(i);
}
else if (vjoy[j][4]==-4) ;
- else if(vjoy[j][4]==-1) lt=pre;
- else if(vjoy[j][4]==-2) rt=pre;
+ else if(vjoy[j][4]==-1) lt[0]=pre;
+ else if(vjoy[j][4]==-2) rt[0]=pre;
else
rv&=~(int)vjoy[j][4];
}
@@ -365,8 +367,8 @@ class GL2JNIView extends GLSurfaceView
reset_analog();
anal_id=-1;
rv=0xFFFF;
- rt=0;
- lt=0;
+ rt[0]=0;
+ lt[0]=0;
for(int j=0;j entry : mMotions.entrySet())
@@ -180,7 +193,13 @@ public class MOGAInput
public void onStateEvent(StateEvent event)
{
- JNIdc.hide_osd();
+ Integer playerNum = GL2JNIActivity.deviceDescriptor_PlayerNum.get(GL2JNIActivity.deviceId_deviceDescriptor.get(event.getControllerId()));
+
+ if (playerNum == null)
+ return;
+
+ if(playerNum == 0)
+ JNIdc.hide_osd();
if (event.getState() == StateEvent.STATE_CONNECTION && event.getAction() == ACTION_CONNECTED) {
Toast.makeText(act.getApplicationContext(), "MOGA Connected!", Toast.LENGTH_SHORT).show();
diff --git a/shell/android/src/com/reicast/emulator/MainActivity.java b/shell/android/src/com/reicast/emulator/MainActivity.java
index 269bc7960..62ed30406 100644
--- a/shell/android/src/com/reicast/emulator/MainActivity.java
+++ b/shell/android/src/com/reicast/emulator/MainActivity.java
@@ -118,9 +118,12 @@ public class MainActivity extends FragmentActivity implements
// Paths
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons
.getResourceId(2, 0)));
- // About
+ // Controllers
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons
.getResourceId(3, 0)));
+ // About
+ navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons
+ .getResourceId(4, 0)));
// Recycle the typed array
navMenuIcons.recycle();
@@ -435,6 +438,17 @@ public class MainActivity extends FragmentActivity implements
frag_tag = "OPTIONS_FRAG";
break;
case 3:
+ fragment = (ControllersFragment) getSupportFragmentManager()
+ .findFragmentByTag("CONTROLLERS_FRAG");
+ if (fragment != null) {
+ if (fragment.isVisible()) {
+ return;
+ }
+ }
+ fragment = new ControllersFragment();
+ frag_tag = "CONTROLLERS_FRAG";
+ break;
+ case 4:
fragment = null;
// vib.vibrate(50);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(