diff --git a/blackberry-qnx/bb10/assets/Controllers.qml b/blackberry-qnx/bb10/assets/Controllers.qml
new file mode 100644
index 0000000000..8b98d33096
--- /dev/null
+++ b/blackberry-qnx/bb10/assets/Controllers.qml
@@ -0,0 +1,130 @@
+import bb.cascades 1.0
+
+Page
+{
+ titleBar: TitleBar {
+ id: players
+ kind: TitleBarKind.Segmented
+ options: [
+ Option {
+ id: p1
+ text: "Player 1"
+ value: 0
+ selected: true
+ },
+ Option {
+ id: p2
+ text: "Player 2"
+ value: 1
+ },
+ Option {
+ id: p3
+ text: "Player 3"
+ value: 2
+ },
+ Option {
+ id: p4
+ text: "Player 4"
+ value: 3
+ }
+ ]
+ }
+
+ actions: [
+ ActionItem {
+ title: "Rescan"
+ ActionBar.placement: ActionBarPlacement.OnBar
+ imageSource: "asset:///images/open.png"
+ onTriggered: {
+ RetroArch.discoverController();
+ }
+ }
+ ]
+
+ Container
+ {
+ Container
+ {
+ preferredWidth: 600
+ horizontalAlignment: HorizontalAlignment.Center
+
+ DropDown
+ {
+ objectName: "dropdown_devices"
+ title: "Device"
+ }
+
+ ListView
+ {
+ id: buttonMapList
+ objectName: "buttonMapList"
+
+ listItemComponents: [
+ ListItemComponent
+ {
+ type: "item"
+
+ Container
+ {
+ id: itemRoot
+ horizontalAlignment: HorizontalAlignment.Center
+ rightPadding: 20
+
+ Divider {}
+
+ Container
+ {
+ horizontalAlignment: HorizontalAlignment.Fill
+ topPadding: 10
+ bottomPadding: 10
+
+
+ layout: DockLayout {
+ }
+
+ Label
+ {
+ horizontalAlignment: HorizontalAlignment.Left
+ verticalAlignment: VerticalAlignment.Center
+ text: ListItemData.label
+ textStyle
+ {
+ base: SystemDefaults.TextStyles.PrimaryText
+ }
+ }
+
+ Label
+ {
+ horizontalAlignment: HorizontalAlignment.Right
+ verticalAlignment: VerticalAlignment.Center
+ text: ListItemData.button
+ textStyle
+ {
+ base: SystemDefaults.TextStyles.PrimaryText
+ }
+ }
+ }
+
+ Divider {}
+ }
+ }
+ ]
+
+ //TODO: Map specific devices instead of 0.
+ onTriggered:
+ {
+ var sym, data;
+ sym = RetroArch.mapButton(0, players.selectedValue, indexPath);
+ data = dataModel.data(indexPath);
+ data["button"] = RetroArch.buttonToString(0, sym);
+ dataModel.replace(indexPath, data);
+ }
+
+ function itemType(data, indexPath)
+ {
+ return "item";
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/blackberry-qnx/bb10/assets/main.qml b/blackberry-qnx/bb10/assets/main.qml
index ab8cd70a1c..fed5ce5c50 100644
--- a/blackberry-qnx/bb10/assets/main.qml
+++ b/blackberry-qnx/bb10/assets/main.qml
@@ -3,9 +3,17 @@ import bb.cascades.pickers 1.0
TabbedPane {
Tab {
+ title: "Main Menu"
MainMenu
{
+ }
+ }
+ Tab {
+ title: "Input"
+ Controllers
+ {
+
}
}
}
diff --git a/blackberry-qnx/bb10/bar-descriptor.xml b/blackberry-qnx/bb10/bar-descriptor.xml
index e04a5c2f4d..64ce5cc9d3 100644
--- a/blackberry-qnx/bb10/bar-descriptor.xml
+++ b/blackberry-qnx/bb10/bar-descriptor.xml
@@ -22,7 +22,7 @@
- 1
+ 2
diff --git a/blackberry-qnx/bb10/src/ButtonMap.cpp b/blackberry-qnx/bb10/src/ButtonMap.cpp
new file mode 100644
index 0000000000..b31634dee9
--- /dev/null
+++ b/blackberry-qnx/bb10/src/ButtonMap.cpp
@@ -0,0 +1,231 @@
+#include
+#include
+#include
+#include
+
+#include "ButtonMap.h"
+#include "RetroArch-Cascades.h"
+#include "input/input_common.h"
+#include "../../frontend_qnx.h"
+
+/*
+ButtonMap_t buttons[] = {
+ { SCREEN_A_GAME_BUTTON, "A button" },
+ { SCREEN_B_GAME_BUTTON, "B button" },
+ { SCREEN_C_GAME_BUTTON, "C button" },
+ { SCREEN_X_GAME_BUTTON, "X button" },
+ { SCREEN_Y_GAME_BUTTON, "Y button" },
+ { SCREEN_Z_GAME_BUTTON, "Z button" },
+ { SCREEN_MENU1_GAME_BUTTON, "Menu1 button" },
+ { SCREEN_MENU2_GAME_BUTTON, "Menu2 button" },
+ { SCREEN_MENU3_GAME_BUTTON, "Menu3 button" },
+ { SCREEN_MENU4_GAME_BUTTON, "Menu4 button" },
+ { SCREEN_L1_GAME_BUTTON, "L1 Button" },
+ { SCREEN_L2_GAME_BUTTON, "L2 Button" },
+ { SCREEN_L3_GAME_BUTTON, "L3 Button" },
+ { SCREEN_R1_GAME_BUTTON, "R1 Button" },
+ { SCREEN_R2_GAME_BUTTON, "R2 Button" },
+ { SCREEN_R3_GAME_BUTTON, "R3 Button" },
+ { SCREEN_DPAD_UP_GAME_BUTTON, "D-Pad Up" },
+ { SCREEN_DPAD_DOWN_GAME_BUTTON, "D-Pad Down" },
+ { SCREEN_DPAD_LEFT_GAME_BUTTON, "D-Pad Left" },
+ { SCREEN_DPAD_RIGHT_GAME_BUTTON, "D-Pad Right" },
+};*/
+
+ButtonMap::ButtonMap(screen_context_t screen_ctx, QString groupId, int coid)
+{
+ this->screen_cxt = screen_ctx;
+ this->groupId = groupId;
+ this->coid = coid;
+
+ const int usage = SCREEN_USAGE_NATIVE | SCREEN_USAGE_WRITE | SCREEN_USAGE_READ;
+ int rc;
+
+ if(screen_create_window_type(&screen_win, screen_cxt, SCREEN_CHILD_WINDOW))
+ {
+ RARCH_ERR("ButtonMap: screen_create_window_type failed.\n");
+ }
+
+ screen_join_window_group(screen_win, (const char *)groupId.toAscii().constData());
+ int format = SCREEN_FORMAT_RGBA8888;
+ screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format);
+
+ screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
+
+ screen_display_t screen_disp;
+ if (screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp))
+ {
+ RARCH_ERR("screen_get_window_property_pv [SCREEN_PROPERTY_DISPLAY] failed.\n");
+ }
+
+ if (screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution))
+ {
+ RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_SIZE] failed.\n");
+ }
+
+ rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, screen_resolution);
+ if (rc) {
+ perror("screen_set_window_property_iv");
+ }
+
+ int z = -10;
+ if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &z) != 0) {
+ return;
+ }
+
+ rc = screen_create_window_buffers(screen_win, 1);
+ if (rc) {
+ perror("screen_create_window_buffers");
+ }
+
+ screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf);
+
+ int bg[] = { SCREEN_BLIT_COLOR, 0x00000000,
+ SCREEN_BLIT_GLOBAL_ALPHA, 0x80,
+ SCREEN_BLIT_END };
+ screen_fill(screen_cxt, screen_buf, bg);
+
+ screen_post_window(screen_win, screen_buf, 1, screen_resolution, 0);
+
+ buttonDataModel = new ArrayDataModel();
+
+ refreshButtonMap();
+}
+
+ButtonMap::~ButtonMap()
+{
+
+}
+
+QString ButtonMap::getLabel(int button)
+{
+ return QString((uint)platform_keys[button].joykey);
+}
+
+//pass in RARCH button enum for button, map to g_setting
+ int ButtonMap::mapNextButtonPressed()
+ {
+ bps_event_t *event = NULL;
+ int sym;
+
+ //use in frontend run loop, get key pressed back, and map
+ int z = 10;
+ if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &z) != 0)
+ {
+ return -1;
+ }
+
+ screen_post_window(screen_win, screen_buf, 1, screen_resolution, 0);
+
+ while(1){
+ if (BPS_SUCCESS != bps_get_event(&event, -1))
+ {
+ fprintf(stderr, "bps_get_event failed\n");
+ break;
+ }
+
+ if (event)
+ {
+ int domain = bps_event_get_domain(event);
+
+ if (domain == screen_get_domain())
+ {
+ screen_event_t screen_event = screen_event_get_event(event);
+ int screen_val;
+ screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
+
+ //TODO: Should we only let the buttons through that we are trying to map?
+ if(screen_val == SCREEN_EVENT_MTOUCH_TOUCH)
+ {
+ //This is touch screen event
+ sym = -1;
+ break;
+ }
+ else if(screen_val == SCREEN_EVENT_KEYBOARD)
+ {
+ screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &sym);
+ sym &= 0xFF;
+ break;
+ }
+ else if( (screen_val == SCREEN_EVENT_GAMEPAD) || (screen_val == SCREEN_EVENT_JOYSTICK) )
+ {
+ screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &sym);
+ break;
+ }
+ }
+ }
+ }
+
+ z = -10;
+ if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &z) != 0) {
+ return -1;
+ }
+
+ screen_post_window(screen_win, screen_buf, 1, screen_resolution, 0);
+
+ return (g_settings.input.binds[player][button].joykey = sym);
+ }
+
+ int ButtonMap::getButtonMapping(int player, int button)
+ {
+ return g_settings.input.binds[player][button].joykey;
+ }
+
+ QString ButtonMap::buttonToString(int button)
+ {
+ for(int i=0;i<20;++i)
+ {
+ if(platform_keys[i].joykey == (uint)button)
+ {
+ return QString(platform_keys[i].desc);
+ }
+ }
+
+ return (button!=NO_BTN) ? QString(button) : QString("Not Mapped");
+ }
+
+ int ButtonMap::requestButtonMapping(screen_device_t device, int player, int button)
+ {
+ //Send message to run thread to start mapping, wait for reply.
+ recv_msg msg;
+ msg.code = RETROARCH_BUTTON_MAP;
+
+ this->device = device;
+ this->player = player;
+ this->button = button;
+
+ return MsgSend(coid, (void*)&msg, sizeof(msg), (void*)NULL, 0);
+ }
+
+void ButtonMap::mapDevice(int index, int player)
+{
+ if (input_qnx.set_keybinds)
+ input_qnx.set_keybinds((void*)&devices[index], devices[index].device, player, 0,
+ (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS));
+
+ refreshButtonMap();
+}
+
+ void ButtonMap::refreshButtonMap()
+ {
+ QVariantMap map;
+
+ buttonDataModel->clear();
+
+ for(int i=0; i<16; ++i)
+ {
+ QString desc = QString(input_config_bind_map[i].desc);
+ int index = desc.indexOf("(");
+ if(index != -1)
+ {
+ desc.truncate(index);
+ }
+
+ map.insert("label",QVariant(desc));
+ map.insert("button", buttonToString(g_settings.input.binds[0][i].joykey));
+ map.insert("type", QVariant("item"));
+ qDebug() << map;
+ qDebug() << "Joykey: " << g_settings.input.binds[0][i].joykey;
+ buttonDataModel->append(map);
+ }
+ }
diff --git a/blackberry-qnx/bb10/src/ButtonMap.h b/blackberry-qnx/bb10/src/ButtonMap.h
new file mode 100644
index 0000000000..99cf2c6adc
--- /dev/null
+++ b/blackberry-qnx/bb10/src/ButtonMap.h
@@ -0,0 +1,57 @@
+#ifndef _BUTTONMAP_H_
+#define _BUTTONMAP_H_
+
+#include
+#include
+
+#include
+#include
+#include "general.h"
+#include "conf/config_file.h"
+#include "file.h"
+
+/*
+typedef struct {
+ int32_t button;
+ QString label;
+} ButtonMap_t;
+*/
+
+using namespace bb::cascades;
+
+class ButtonMap
+{
+
+public:
+ ButtonMap(screen_context_t screen_cxt, QString groupId, int coid);
+ ~ ButtonMap();
+
+ QString getLabel(int button);
+ //pass in RARCH button enum for button, map to g_setting
+ int mapNextButtonPressed();
+ //Call in our emulator thread with seperate screen_cxt
+ int getButtonMapping(int player, int button);
+ //Call from frontend
+ int requestButtonMapping(screen_device_t device, int player, int button);
+ void refreshButtonMap();
+ void mapDevice(int index, int player);
+
+ QString buttonToString(int button);
+
+ ArrayDataModel *buttonDataModel;
+
+private:
+ screen_context_t screen_cxt;
+ screen_window_t screen_win;
+ screen_buffer_t screen_buf;
+ screen_device_t device;
+ int player;
+ int button;
+ int screen_resolution[2];
+ QString groupId;
+ int coid;
+
+ //use g_settings.input.binds[port][i].joykey = SCREEN_* for mapping
+};
+
+#endif
diff --git a/blackberry-qnx/bb10/src/RetroArch-Cascades.cpp b/blackberry-qnx/bb10/src/RetroArch-Cascades.cpp
index c2529ed563..b0a32655cb 100644
--- a/blackberry-qnx/bb10/src/RetroArch-Cascades.cpp
+++ b/blackberry-qnx/bb10/src/RetroArch-Cascades.cpp
@@ -21,6 +21,8 @@
#include "frontend/menu/rgui.h"
#endif
+#include "../../frontend_qnx.h"
+
#include
#include
#include
@@ -29,6 +31,8 @@
#include
#include
#include
+#include
+
#include
#include
@@ -43,7 +47,11 @@ using namespace bb::cascades;
using namespace bb::data;
using namespace bb::device;
+extern screen_window_t screen_win;
+extern screen_context_t screen_ctx;
+
//Use after calling findCores
+//If we allow user added libs, this needs to be error checked
#define GET_CORE_INFO(x, y) coreInfo[coreList[x]].toMap()[y].toString()
RetroArch::RetroArch()
@@ -60,10 +68,14 @@ RetroArch::RetroArch()
this, SLOT(onRotationCompleted()));
rarch_main_clear_state();
+ config_load();
strlcpy(g_settings.libretro, "app/native/lib", sizeof(g_settings.libretro));
coreSelectedIndex = -1;
+ //Stop config overwritting values
+ g_extern.block_config_read = true;
+
QmlDocument *qml = QmlDocument::create("asset:///main.qml");
if (!qml->hasErrors())
@@ -81,6 +93,17 @@ RetroArch::RetroArch()
Application::instance()->setScene(mAppPane);
+ screen_create_context(&screen_ctx, 0);
+ input_qnx.init();
+ buttonMap = new ButtonMap(screen_ctx, (const char*)Application::instance()->mainWindow()->groupId().toAscii().constData(), coid);
+
+ deviceSelection = mAppPane->findChild("dropdown_devices");
+ connect(deviceSelection, SIGNAL(selectedValueChanged(QVariant)), this, SLOT(onDeviceSelected(QVariant)));
+ findDevices();
+
+ //Setup the datamodel for button mapping.
+ mAppPane->findChild("buttonMapList")->setDataModel(buttonMap->buttonDataModel);
+
// Start the thread in which we render to the custom window.
start();
}
@@ -103,14 +126,30 @@ void RetroArch::aboutToQuit()
wait();
}
-extern screen_window_t screen_win;
-extern screen_context_t screen_ctx;
void RetroArch::run()
{
int rcvid = -1;
recv_msg msg;
- while (true) {
+ bps_initialize();
+
+ if (screen_request_events(screen_ctx) != BPS_SUCCESS)
+ {
+ RARCH_ERR("screen_request_events failed.\n");
+ }
+
+ if (navigator_request_events(0) != BPS_SUCCESS)
+ {
+ RARCH_ERR("navigator_request_events failed.\n");
+ }
+
+ if (navigator_rotation_lock(false) != BPS_SUCCESS)
+ {
+ RARCH_ERR("navigator_location_lock failed.\n");
+ }
+
+ while (true)
+ {
rcvid = MsgReceive(chid, &msg, sizeof(msg), 0);
if (rcvid > 0)
@@ -123,29 +162,15 @@ void RetroArch::run()
MsgReply(rcvid,0,NULL,0);
- screen_create_context(&screen_ctx, 0);
-
- bps_initialize();
-
- if (screen_request_events(screen_ctx) != BPS_SUCCESS)
+ if (screen_create_window_type(&screen_win, screen_ctx, SCREEN_CHILD_WINDOW) != BPS_SUCCESS)
{
- RARCH_ERR("screen_request_events failed.\n");
+ RARCH_ERR("Screen create window failed.\n");
}
-
- if (navigator_request_events(0) != BPS_SUCCESS)
+ if (screen_join_window_group(screen_win, (const char*)Application::instance()->mainWindow()->groupId().toAscii().constData()) != BPS_SUCCESS)
{
- RARCH_ERR("navigator_request_events failed.\n");
+ RARCH_ERR("Screen join window group failed.\n");
}
- if (navigator_rotation_lock(false) != BPS_SUCCESS)
- {
- RARCH_ERR("navigator_location_lock failed.\n");
- }
-
- screen_create_window_type(&screen_win, screen_ctx, SCREEN_CHILD_WINDOW);
-
- screen_join_window_group(screen_win, Application::instance()->mainWindow()->groupId().toAscii().constData());
-
char *win_id = "RetroArch_Emulator_Window";
screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_ID_STRING, strlen(win_id), win_id);
@@ -159,6 +184,10 @@ void RetroArch::run()
rarch_main(0, NULL);
break;
}
+ //The class should probably be it's own QThread, simplify things
+ case RETROARCH_BUTTON_MAP:
+ MsgReply(rcvid, buttonMap->mapNextButtonPressed(), NULL, 0);
+ break;
case RETROARCH_EXIT:
MsgReply(rcvid,0,NULL,0);
goto exit;
@@ -230,6 +259,11 @@ void RetroArch::onCoreSelected(QVariant value)
qDebug() << "Supported Extensions: " << romExtensions;
}
+void RetroArch::onDeviceSelected(QVariant value)
+{
+
+}
+
/*
* Functions
*/
@@ -260,8 +294,10 @@ void RetroArch::findCores()
int count=0, i=0;
dirp = opendir(g_settings.libretro);
- if( dirp != NULL ) {
- for(;;) {
+ if( dirp != NULL )
+ {
+ for(;;)
+ {
direntp = readdir( dirp );
if( direntp == NULL ) break;
count++;
@@ -269,14 +305,16 @@ void RetroArch::findCores()
fflush(stdout);
rewinddir(dirp);
- if(count==2){
+ if(count==2)
+ {
printf("No Cores Found");fflush(stdout);
}
coreList = (char**)malloc(count*sizeof(char*));
count = 0;
- for(;;){
+ for(;;)
+ {
direntp = readdir( dirp );
if( direntp == NULL ) break;
coreList[count++] = strdup((char*)direntp->d_name);
@@ -304,6 +342,29 @@ void RetroArch::findCores()
closedir(dirp);
}
+void RetroArch::findDevices()
+{
+ //Find all connected devices.
+ Option *tmp;
+
+ deviceSelection->removeAll();
+
+ //Populate DropDown
+ for (int i = 0; i < pads_connected; ++i)
+ {
+ tmp = Option::create().text(devices[i].device_name)
+ .value(i);
+
+ deviceSelection->add(tmp);
+
+ //QML shows player 1 by default, so set dropdown to their controller.
+ if(devices[i].port == 0)
+ {
+ deviceSelection->setSelectedIndex(i);
+ }
+ }
+}
+
void RetroArch::initRASettings()
{
strlcpy(g_settings.libretro,(char *)core.toAscii().constData(), sizeof(g_settings.libretro));
@@ -311,7 +372,32 @@ void RetroArch::initRASettings()
HardwareInfo *hwInfo = new HardwareInfo();
+ //TODO: Check of we have a controller active.
if(!hwInfo->isPhysicalKeyboardDevice())
strlcpy(g_settings.input.overlay, GET_CORE_INFO(coreSelectedIndex, "default_overlay").toAscii().constData(), sizeof(g_settings.input.overlay));
}
+int RetroArch::mapButton(void* deviceVp, int player, int button)
+{
+ screen_device_t device = (screen_device_t)deviceVp;
+ return buttonMap->requestButtonMapping(device, player, button);
+}
+
+QString RetroArch::buttonToString(void* deviceVp, int button)
+{
+ //TODO: Check deviceVp, gamepad/keyboard and return accordingly.
+ if(g_settings.input.device[0] == DEVICE_KEYPAD || g_settings.input.device[0] == DEVICE_KEYBOARD)
+ return QString(button);
+ else
+ return buttonMap->buttonToString(button);
+}
+
+extern "C" void discoverControllers();
+void RetroArch::discoverController()
+{
+ //TODO: Check device, gamepad/keyboard and return accordingly.
+ discoverControllers();
+ findDevices();
+ buttonMap->refreshButtonMap();
+ return;
+}
diff --git a/blackberry-qnx/bb10/src/RetroArch-Cascades.h b/blackberry-qnx/bb10/src/RetroArch-Cascades.h
index aa58391922..14d51ca128 100644
--- a/blackberry-qnx/bb10/src/RetroArch-Cascades.h
+++ b/blackberry-qnx/bb10/src/RetroArch-Cascades.h
@@ -8,6 +8,7 @@
#include
#include
+#include "ButtonMap.h"
using namespace bb::cascades;
@@ -33,6 +34,10 @@ public:
Q_INVOKABLE void startEmulator();
Q_INVOKABLE void findCores();
+ Q_INVOKABLE void findDevices();
+ Q_INVOKABLE int mapButton(void* device, int player, int button);
+ Q_INVOKABLE QString buttonToString(void* deviceVp, int button);
+ Q_INVOKABLE void discoverController();
signals:
void romChanged(QString);
@@ -43,6 +48,7 @@ public slots:
void aboutToQuit();
void onRotationCompleted();
void onCoreSelected(QVariant);
+ void onDeviceSelected(QVariant);
private:
/**
@@ -67,21 +73,25 @@ private:
int chid, coid;
int state;
DropDown *coreSelection;
+ DropDown *deviceSelection;
QVariantMap coreInfo;
char **coreList;
int coreSelectedIndex;
+
+ ButtonMap *buttonMap;
};
enum {
RETROARCH_RUNNING,
RETROARCH_START_REQUESTED,
+ RETROARCH_BUTTON_MAP,
RETROARCH_EXIT
};
typedef union {
_pulse pulse;
- int code;
+ int code;
} recv_msg;
#endif
diff --git a/blackberry-qnx/frontend_qnx.h b/blackberry-qnx/frontend_qnx.h
new file mode 100644
index 0000000000..9239330794
--- /dev/null
+++ b/blackberry-qnx/frontend_qnx.h
@@ -0,0 +1,61 @@
+#ifndef _FRONTENDQNX_H_
+#define _FRONTENDQNX_H_
+
+#define MAX_PADS 8
+
+//Internal helper functions
+typedef struct {
+ // Static device info.
+#ifdef HAVE_BB10
+ screen_device_t handle;
+#endif
+ int type;
+ int analogCount;
+ int buttonCount;
+ char id[64];
+ char vendor[64];
+ char product[64];
+
+ char device_name[64];
+ int device;
+ int port;
+
+ // Current state.
+ int buttons;
+ int analog0[3];
+ int analog1[3];
+} input_device_t;
+
+//Device struct to port mapping
+extern input_device_t *port_device[MAX_PADS];
+
+extern unsigned pads_connected;
+
+#ifdef HAVE_BB10
+const struct platform_bind platform_keys[] = {
+ { SCREEN_A_GAME_BUTTON, "A button" },
+ { SCREEN_B_GAME_BUTTON, "B button" },
+ { SCREEN_C_GAME_BUTTON, "C button" },
+ { SCREEN_X_GAME_BUTTON, "X button" },
+ { SCREEN_Y_GAME_BUTTON, "Y button" },
+ { SCREEN_Z_GAME_BUTTON, "Z button" },
+ { SCREEN_MENU1_GAME_BUTTON, "Menu1 button" },
+ { SCREEN_MENU2_GAME_BUTTON, "Menu2 button" },
+ { SCREEN_MENU3_GAME_BUTTON, "Menu3 button" },
+ { SCREEN_MENU4_GAME_BUTTON, "Menu4 button" },
+ { SCREEN_L1_GAME_BUTTON, "L1 Button" },
+ { SCREEN_L2_GAME_BUTTON, "L2 Button" },
+ { SCREEN_L3_GAME_BUTTON, "L3 Button" },
+ { SCREEN_R1_GAME_BUTTON, "R1 Button" },
+ { SCREEN_R2_GAME_BUTTON, "R2 Button" },
+ { SCREEN_R3_GAME_BUTTON, "R3 Button" },
+ { SCREEN_DPAD_UP_GAME_BUTTON, "D-Pad Up" },
+ { SCREEN_DPAD_DOWN_GAME_BUTTON, "D-Pad Down" },
+ { SCREEN_DPAD_LEFT_GAME_BUTTON, "D-Pad Left" },
+ { SCREEN_DPAD_RIGHT_GAME_BUTTON, "D-Pad Right" },
+};
+#endif
+
+extern input_device_t devices[MAX_PADS];
+
+#endif
diff --git a/blackberry-qnx/qnx_input.c b/blackberry-qnx/qnx_input.c
index 1525ee1c05..f5dba9be88 100644
--- a/blackberry-qnx/qnx_input.c
+++ b/blackberry-qnx/qnx_input.c
@@ -20,8 +20,9 @@
#include
#include
+#include "frontend_qnx.h"
+
#define MAX_TOUCH 16
-#define MAX_PADS 8
struct touches
{
@@ -33,56 +34,15 @@ struct touches
static struct touches touch[MAX_TOUCH];
static unsigned touch_count;
-//Internal helper functions
-typedef struct {
- // Static device info.
-#ifdef HAVE_BB10
- screen_device_t handle;
-#endif
- int type;
- int analogCount;
- int buttonCount;
- char id[64];
- char vendor[64];
- char product[64];
-
- // Current state.
- int buttons;
- int analog0[3];
- int analog1[3];
-} input_device_t;
-
input_device_t devices[MAX_PADS];
+input_device_t *port_device[MAX_PADS];
-static unsigned pads_connected;
+unsigned pads_connected;
static void qnx_input_autodetect_gamepad(input_device_t* controller);
+static void initController(input_device_t* controller);
#ifdef HAVE_BB10
-
-const struct platform_bind platform_keys[] = {
- { SCREEN_A_GAME_BUTTON, "A button" },
- { SCREEN_B_GAME_BUTTON, "B button" },
- { SCREEN_C_GAME_BUTTON, "C button" },
- { SCREEN_X_GAME_BUTTON, "X button" },
- { SCREEN_Y_GAME_BUTTON, "Y button" },
- { SCREEN_Z_GAME_BUTTON, "Z button" },
- { SCREEN_MENU1_GAME_BUTTON, "Menu1 button" },
- { SCREEN_MENU2_GAME_BUTTON, "Menu2 button" },
- { SCREEN_MENU3_GAME_BUTTON, "Menu3 button" },
- { SCREEN_MENU4_GAME_BUTTON, "Menu4 button" },
- { SCREEN_L1_GAME_BUTTON, "L1 Button" },
- { SCREEN_L2_GAME_BUTTON, "L2 Button" },
- { SCREEN_L3_GAME_BUTTON, "L3 Button" },
- { SCREEN_R1_GAME_BUTTON, "R1 Button" },
- { SCREEN_R2_GAME_BUTTON, "R2 Button" },
- { SCREEN_R3_GAME_BUTTON, "R3 Button" },
- { SCREEN_DPAD_UP_GAME_BUTTON, "D-Pad Up" },
- { SCREEN_DPAD_DOWN_GAME_BUTTON, "D-Pad Down" },
- { SCREEN_DPAD_LEFT_GAME_BUTTON, "D-Pad Left" },
- { SCREEN_DPAD_RIGHT_GAME_BUTTON, "D-Pad Right" },
-};
-
static void process_gamepad_event(screen_event_t screen_event, int type)
{
screen_device_t device;
@@ -152,7 +112,7 @@ static void loadController(input_device_t* controller)
}
extern screen_context_t screen_ctx;
-static void discoverControllers()
+void discoverControllers()
{
// Get an array of all available devices.
int deviceCount;
@@ -163,16 +123,27 @@ static void discoverControllers()
// Scan the list for gamepad and joystick devices.
int i;
+ for(i=0;ibuttons = 0;
controller->analog0[0] = controller->analog0[1] = controller->analog0[2] = 0;
controller->analog1[0] = controller->analog1[1] = controller->analog1[2] = 0;
+ controller->port = -1;
+ controller->device = -1;
memset(controller->id, 0, sizeof(controller->id));
}
static void qnx_input_autodetect_gamepad(input_device_t* controller)
{
- int device;
-
//ID: A-BBBB-CCCC-D.D
//A is the device's index in the array returned by screen_get_context_property_pv()
//BBBB is the device's Vendor ID (in hexadecimal)
//CCCC is the device's Product ID (also in hexadecimal)
//D.D is the device's version number
if (strstr(controller->id, "057E-0306"))
- device = DEVICE_WIIMOTE;
+ {
+ controller->device = DEVICE_WIIMOTE;
+ strlcpy(controller->device_name, "Wiimote", sizeof(controller->device_name));
+ }
else if (strstr(controller->id, "0A5C-8502"))
- device = DEVICE_KEYBOARD;
+ {
+ controller->device = DEVICE_KEYBOARD;
+ strlcpy(controller->device_name, "BlackBerry BT Keyboard", sizeof(controller->device_name));
+ }
else if (strstr(controller->id, "qwerty:bb35"))
- device = DEVICE_KEYPAD;
- else if (controller->id)
- device = DEVICE_UNKNOWN;
+ {
+ controller->device = DEVICE_KEYPAD;
+ strlcpy(controller->device_name, "BlackBerry Q10 Keypad", sizeof(controller->device_name));
+ }
+ else if (controller->id[0])
+ {
+ controller->device = DEVICE_UNKNOWN;
+ strlcpy(controller->device_name, "Unknown", sizeof(controller->device_name));
+ }
else
- device = DEVICE_NONE;
+ {
+ controller->device = DEVICE_NONE;
+ strlcpy(controller->device_name, "None", sizeof(controller->device_name));
+ }
- if (driver.input->set_keybinds)
- driver.input->set_keybinds((void*)controller, device, pads_connected, 0,
+ if (input_qnx.set_keybinds)
+ input_qnx.set_keybinds((void*)controller, controller->device, pads_connected, 0,
(1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS));
}
@@ -267,10 +255,13 @@ static void process_keyboard_event(screen_event_t event, int type)
controller = &devices[0];
#endif
+ if(controller->port == -1)
+ return;
+
int b;
for (b = 0; b < RARCH_FIRST_CUSTOM_BIND; ++b)
{
- if ((unsigned int)g_settings.input.binds[i][b].joykey == (unsigned int)(sym&0xFF))
+ if ((unsigned int)g_settings.input.binds[controller->port][b].joykey == (unsigned int)(sym&0xFF))
{
if (flags & KEY_DOWN)
controller->buttons |= 1 << b;
@@ -450,21 +441,28 @@ static void handle_navigator_event(bps_event_t *event)
static void *qnx_input_init(void)
{
int i;
+ static int initialized = 0;
+
+ if(initialized)
+ return (void*)-1;
for (i = 0; i < MAX_TOUCH; ++i)
touch[i].contact_id = -1;
for (i = 0; i < MAX_PADS; ++i)
+ {
initController(&devices[i]);
+ port_device[i] = (input_device_t*)-1;
+ }
#ifdef HAVE_BB10
- pads_connected = 0;
-
//Find currently connected gamepads
discoverControllers();
#else
init_playbook_keyboard();
#endif
+ initialized = 1;
+
return (void*)-1;
}
@@ -504,27 +502,33 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke
switch (device)
{
case RETRO_DEVICE_JOYPAD:
- if (g_settings.input.device[port] == DEVICE_KEYBOARD || g_settings.input.device[port] == DEVICE_KEYPAD)
- return ((devices[port].buttons & (1 << id)) && (port < pads_connected));
- else
- return ((devices[port].buttons & retro_keybinds[port][id].joykey) && (port < pads_connected));
+ if(port_device[port] != (input_device_t*)-1)
+ {
+ if (g_settings.input.device[port] == DEVICE_KEYBOARD || g_settings.input.device[port] == DEVICE_KEYPAD)
+ return ((port_device[port]->buttons & (1 << id)) && (port < pads_connected) );
+ else
+ return ((port_device[port]->buttons & retro_keybinds[port][id].joykey) && (port < pads_connected));
+ }
#ifdef HAVE_BB10
case RETRO_DEVICE_ANALOG:
//Need to return [-0x8000, 0x7fff]
//Gamepad API gives us [-128, 127] with (0,0) center
//Untested
- switch ((index << 1) | id)
+ if(port_device[port] != (input_device_t*)-1)
{
- case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_X:
- return devices[port].analog0[0] * 256;
- case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
- return devices[port].analog0[1] * 256;
- case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_X:
- return devices[port].analog1[0] * 256;
- case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
- return devices[port].analog1[1] * 256;
- default:
- break;
+ switch ((index << 1) | id)
+ {
+ case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_X:
+ return port_device[port]->analog0[0] * 256;
+ case (RETRO_DEVICE_INDEX_ANALOG_LEFT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
+ return port_device[port]->analog0[1] * 256;
+ case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_X:
+ return port_device[port]->analog1[0] * 256;
+ case (RETRO_DEVICE_INDEX_ANALOG_RIGHT << 1) | RETRO_DEVICE_ID_ANALOG_Y:
+ return port_device[port]->analog1[1] * 256;
+ default:
+ break;
+ }
}
break;
#endif
@@ -563,6 +567,7 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
uint64_t *key = &g_settings.input.binds[port][id].joykey;
uint64_t joykey = *key;
size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]);
+ input_device_t *controller = (input_device_t*)data;
(void)device;
@@ -615,6 +620,7 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
{
#ifdef HAVE_BB10
case DEVICE_WIIMOTE:
+ //TODO:Have enum lookup for string
strlcpy(g_settings.input.device_names[port], "Wiimote",
sizeof(g_settings.input.device_names[port]));
g_settings.input.device[port] = device;
@@ -635,6 +641,8 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].def_joykey = SCREEN_L3_GAME_BUTTON;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].def_joykey = SCREEN_R3_GAME_BUTTON;
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
+ controller->port = port;
+ port_device[port] = controller;
break;
case DEVICE_KEYPAD:
strlcpy(g_settings.input.device_names[port], "BlackBerry Q10 Keypad",
@@ -657,6 +665,8 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].def_joykey = 0;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].def_joykey = 0;
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
+ controller->port = port;
+ port_device[port] = controller;
break;
#endif
case DEVICE_KEYBOARD:
@@ -680,6 +690,8 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].def_joykey = 0;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].def_joykey = 0;
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
+ controller->port = port;
+ port_device[port] = controller;
break;
#ifdef HAVE_BB10
case DEVICE_UNKNOWN:
@@ -703,6 +715,8 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].def_joykey = SCREEN_L3_GAME_BUTTON;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].def_joykey = SCREEN_R3_GAME_BUTTON;
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
+ controller->port = port;
+ port_device[port] = controller;
break;
case DEVICE_NONE:
default:
@@ -725,6 +739,8 @@ static void qnx_input_set_keybinds(void *data, unsigned device, unsigned port,
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R2].def_joykey = 0;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].def_joykey = 0;
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].def_joykey = 0;
+ controller->port = -1;
+ port_device[port] = -1;
break;
#endif
}
diff --git a/driver.h b/driver.h
index 2bd3c9c55d..6267c2af05 100644
--- a/driver.h
+++ b/driver.h
@@ -522,6 +522,7 @@ extern const input_driver_t input_gx;
extern const input_driver_t input_xinput;
extern const input_driver_t input_linuxraw;
extern const input_driver_t input_ios;
+extern const input_driver_t input_qnx;
extern const input_driver_t input_null;
#include "driver_funcs.h"
diff --git a/frontend/frontend_bbqnx.c b/frontend/frontend_bbqnx.c
index c9765ffba9..81b4e7f24d 100644
--- a/frontend/frontend_bbqnx.c
+++ b/frontend/frontend_bbqnx.c
@@ -30,11 +30,11 @@ int rarch_main(int argc, char *argv[])
bps_initialize();
rarch_main_clear_state();
strlcpy(g_settings.libretro, "app/native/lib", sizeof(g_settings.libretro));
-#endif
strlcpy(g_extern.config_path, "app/native/retroarch.cfg", sizeof(g_extern.config_path));
strlcpy(g_settings.video.shader_dir, "app/native/shaders_glsl", sizeof(g_settings.video.shader_dir));
config_load();
+#endif
g_extern.verbose = true;
diff --git a/griffin/griffin.c b/griffin/griffin.c
index fef0790200..0893c69a8d 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -403,7 +403,7 @@ MAIN
#include "../frontend/frontend_ios.c"
#endif
-#if defined(__QNX__) || !defined(RARCH_MOBILE)
+#if (defined(__QNX__) && !defined(HAVE_BB10)) || !defined(RARCH_MOBILE)
#include "../frontend/frontend.c"
#endif