mirror of
https://github.com/libretro/RetroArch
synced 2025-02-20 15:40:44 +00:00
(iOS) Add initial MFi game controller support.
This commit is contained in:
parent
f6362b459c
commit
aee6bce679
@ -20,6 +20,8 @@
|
||||
96337E82176AC6E5004685F3 /* utility.m in Sources */ = {isa = PBXBuildFile; fileRef = 96337E81176AC6E5004685F3 /* utility.m */; };
|
||||
96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; };
|
||||
96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; };
|
||||
963C3C32186E3D2600A6EB1E /* apple_gamecontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 963C3C31186E3D2600A6EB1E /* apple_gamecontroller.m */; };
|
||||
963C3C34186E3DED00A6EB1E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 963C3C33186E3DED00A6EB1E /* GameController.framework */; settings = {ATTRIBUTES = (Required, ); }; };
|
||||
963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; };
|
||||
9646869517BBBEAE00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869417BBBEAE00C5EA69 /* platform.m */; };
|
||||
966B9CBD16E41E7A005B61E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */; };
|
||||
@ -54,6 +56,9 @@
|
||||
96355CD11788CF190010DBFA /* RetroArch_Apple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_Apple.h; sourceTree = "<group>"; };
|
||||
96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
963C3C30186E3D2600A6EB1E /* apple_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = apple_gamecontroller.h; sourceTree = "<group>"; };
|
||||
963C3C31186E3D2600A6EB1E /* apple_gamecontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = apple_gamecontroller.m; sourceTree = "<group>"; };
|
||||
963C3C33186E3DED00A6EB1E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||
963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = "<group>"; };
|
||||
9646869417BBBEAE00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = iOS/platform.m; sourceTree = SOURCE_ROOT; };
|
||||
966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
@ -86,6 +91,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
963C3C34186E3DED00A6EB1E /* GameController.framework in Frameworks */,
|
||||
50CCC828185E0E7D001F5BC8 /* CoreLocation.framework in Frameworks */,
|
||||
501881EE184BB54C006F665D /* CoreMedia.framework in Frameworks */,
|
||||
501881EC184BAD6D006F665D /* AVFoundation.framework in Frameworks */,
|
||||
@ -144,6 +150,7 @@
|
||||
96AFAE2816C1D4EA009DE44C /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
963C3C33186E3DED00A6EB1E /* GameController.framework */,
|
||||
50CCC827185E0E7D001F5BC8 /* CoreLocation.framework */,
|
||||
501881ED184BB54C006F665D /* CoreMedia.framework */,
|
||||
501881EB184BAD6D006F665D /* AVFoundation.framework */,
|
||||
@ -162,6 +169,8 @@
|
||||
96AFAE3316C1D4EA009DE44C /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
963C3C30186E3D2600A6EB1E /* apple_gamecontroller.h */,
|
||||
963C3C31186E3D2600A6EB1E /* apple_gamecontroller.m */,
|
||||
509FC978183F9F18007A5A30 /* menu.m */,
|
||||
9646869417BBBEAE00C5EA69 /* platform.m */,
|
||||
967894571788EAAE00D6CA69 /* browser.m */,
|
||||
@ -304,6 +313,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
963C3C32186E3D2600A6EB1E /* apple_gamecontroller.m in Sources */,
|
||||
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */,
|
||||
963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */,
|
||||
D48581DE16F823F9004BEB17 /* griffin.c in Sources */,
|
||||
|
22
apple/common/apple_gamecontroller.h
Normal file
22
apple/common/apple_gamecontroller.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __APPLE_RARCH_GAMECONTROLLER_H__
|
||||
#define __APPLE_RARCH_GAMECONTROLLER_H__
|
||||
|
||||
void apple_gamecontroller_init();
|
||||
void apple_gamecontroller_poll_all();
|
||||
|
||||
#endif
|
125
apple/common/apple_gamecontroller.m
Normal file
125
apple/common/apple_gamecontroller.m
Normal file
@ -0,0 +1,125 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Availability.h>
|
||||
|
||||
#if __IPHONE_7_0
|
||||
|
||||
#define IS_PRESSED(x) (x.value > .01f)
|
||||
|
||||
#import <GameController/GameController.h>
|
||||
#include "apple_input.h"
|
||||
|
||||
static void apple_gamecontroller_poll(GCController* controller)
|
||||
{
|
||||
if (!controller || controller.playerIndex == MAX_PLAYERS)
|
||||
return;
|
||||
|
||||
uint32_t slot = controller.playerIndex;
|
||||
g_current_input_data.pad_buttons[slot] = 0;
|
||||
memset(g_current_input_data.pad_axis[slot], 0, sizeof(g_current_input_data.pad_axis[0]));
|
||||
|
||||
if (controller.extendedGamepad)
|
||||
{
|
||||
GCExtendedGamepad* gp = controller.extendedGamepad;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.up) ? 1 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.down) ? 2 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.left) ? 4 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.right) ? 8 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonA) ? 16 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonB) ? 32 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonX) ? 64 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonY) ? 128 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.leftShoulder) ? 256 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.rightShoulder) ? 512 : 0;
|
||||
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.leftTrigger) ? 1024 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.rightTrigger) ? 2048 : 0;
|
||||
g_current_input_data.pad_axis[slot][0] = gp.leftThumbstick.xAxis.value * 32767.0f;
|
||||
g_current_input_data.pad_axis[slot][1] = gp.leftThumbstick.yAxis.value * 32767.0f;
|
||||
g_current_input_data.pad_axis[slot][2] = gp.rightThumbstick.xAxis.value * 32767.0f;
|
||||
g_current_input_data.pad_axis[slot][3] = gp.rightThumbstick.yAxis.value * 32767.0f;
|
||||
}
|
||||
else if (controller.gamepad)
|
||||
{
|
||||
GCGamepad* gp = controller.gamepad;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.up) ? 1 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.down) ? 2 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.left) ? 4 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.dpad.right) ? 8 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonA) ? 16 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonB) ? 32 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonX) ? 64 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.buttonY) ? 128 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.leftShoulder) ? 256 : 0;
|
||||
g_current_input_data.pad_buttons[slot] |= IS_PRESSED(gp.rightShoulder) ? 512 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void apple_gamecontroller_poll_all()
|
||||
{
|
||||
NSArray* controllers = [GCController controllers];
|
||||
|
||||
for (int i = 0; i != [controllers count]; i ++)
|
||||
apple_gamecontroller_poll([controllers objectAtIndex:i]);
|
||||
}
|
||||
|
||||
void apple_gamecontroller_connect(GCController* controller)
|
||||
{
|
||||
int32_t slot = apple_joypad_connect_gcapi();
|
||||
controller.playerIndex = (slot >= 0 && slot < MAX_PLAYERS) ? slot : GCControllerPlayerIndexUnset;
|
||||
|
||||
/*
|
||||
if (controller.playerIndex == GCControllerPlayerIndexUnset)
|
||||
return;
|
||||
else if (controller.extendedGamepad)
|
||||
controller.extendedGamepad.valueChangedHandler =
|
||||
^(GCExtendedGamepad *gamepad, GCControllerElement *element) { apple_gamecontroller_poll(gamepad.controller); };
|
||||
else if (controller.gamepad)
|
||||
controller.gamepad.valueChangedHandler =
|
||||
^(GCGamepad *gamepad, GCControllerElement *element) { apple_gamecontroller_poll(gamepad.controller); };
|
||||
*/
|
||||
}
|
||||
|
||||
void apple_gamecontroller_disconnect(GCController* controller)
|
||||
{
|
||||
if (controller.playerIndex == GCControllerPlayerIndexUnset)
|
||||
return;
|
||||
|
||||
apple_joypad_disconnect(controller.playerIndex);
|
||||
}
|
||||
|
||||
void apple_gamecontroller_init()
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) { apple_gamecontroller_connect([note object]); } ];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) { apple_gamecontroller_disconnect([note object]); } ];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void apple_gamecontroller_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void apple_gamecontroller_poll_all()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "apple_gamecontroller.h"
|
||||
#include "input/input_common.h"
|
||||
#include "apple_input.h"
|
||||
#include "general.h"
|
||||
@ -108,6 +109,7 @@ void apple_input_handle_key_event(unsigned keycode, bool down)
|
||||
|
||||
int32_t apple_input_find_any_key(void)
|
||||
{
|
||||
apple_gamecontroller_poll_all();
|
||||
input_init_keyboard_lut(apple_key_map_hidusage);
|
||||
|
||||
for (int i = 0; apple_key_name_map[i].hid_id; i++)
|
||||
@ -119,6 +121,8 @@ int32_t apple_input_find_any_key(void)
|
||||
|
||||
int32_t apple_input_find_any_button(uint32_t port)
|
||||
{
|
||||
apple_gamecontroller_poll_all();
|
||||
|
||||
uint32_t buttons = g_current_input_data.pad_buttons[port] |
|
||||
((port == 0) ? apple_input_get_icade_buttons() : 0);
|
||||
|
||||
@ -132,6 +136,8 @@ int32_t apple_input_find_any_button(uint32_t port)
|
||||
|
||||
int32_t apple_input_find_any_axis(uint32_t port)
|
||||
{
|
||||
apple_gamecontroller_poll_all();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value = g_current_input_data.pad_axis[port][i];
|
||||
@ -167,6 +173,7 @@ static void *apple_input_init(void)
|
||||
|
||||
static void apple_input_poll(void *data)
|
||||
{
|
||||
apple_gamecontroller_poll_all();
|
||||
memcpy(&g_polled_input_data, &g_current_input_data, sizeof(apple_input_data_t));
|
||||
|
||||
for (int i = 0; i != g_polled_input_data.touch_count; i ++)
|
||||
|
@ -55,6 +55,7 @@ struct apple_pad_interface
|
||||
|
||||
// Joypad data
|
||||
int32_t apple_joypad_connect(const char* name, struct apple_pad_connection* connection);
|
||||
int32_t apple_joypad_connect_gcapi();
|
||||
void apple_joypad_disconnect(uint32_t slot);
|
||||
void apple_joypad_packet(uint32_t slot, uint8_t* data, uint32_t length);
|
||||
|
||||
|
@ -33,6 +33,8 @@ typedef struct
|
||||
bool used;
|
||||
struct apple_pad_interface* iface;
|
||||
void* data;
|
||||
|
||||
bool is_gcapi;
|
||||
} joypad_slot_t;
|
||||
|
||||
static joypad_slot_t slots[MAX_PLAYERS];
|
||||
@ -73,6 +75,20 @@ int32_t apple_joypad_connect(const char* name, struct apple_pad_connection* conn
|
||||
return slot;
|
||||
}
|
||||
|
||||
int32_t apple_joypad_connect_gcapi()
|
||||
{
|
||||
int32_t slot = find_empty_slot();
|
||||
|
||||
if (slot >= 0 && slot < MAX_PLAYERS)
|
||||
{
|
||||
joypad_slot_t* s = &slots[slot];
|
||||
s->used = true;
|
||||
s->is_gcapi = true;
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
void apple_joypad_disconnect(uint32_t slot)
|
||||
{
|
||||
if (slot < MAX_PLAYERS && slots[slot].used)
|
||||
@ -82,7 +98,7 @@ void apple_joypad_disconnect(uint32_t slot)
|
||||
if (s->iface && s->data)
|
||||
s->iface->disconnect(s->data);
|
||||
|
||||
s->used = false;
|
||||
memset(s, 0, sizeof(joypad_slot_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "apple/common/apple_input.h"
|
||||
#include "apple/common/setting_data.h"
|
||||
#include "apple/common/apple_gamecontroller.h"
|
||||
#include "menu.h"
|
||||
|
||||
#import "views.h"
|
||||
@ -221,7 +222,9 @@ static void handle_touch_event(NSArray* touches)
|
||||
|
||||
if (!core_list || core_list->count == 0)
|
||||
apple_display_alert(@"No libretro cores were found. You will not be able to run any content.", 0);
|
||||
|
||||
|
||||
apple_gamecontroller_init();
|
||||
|
||||
// Load system config
|
||||
const rarch_setting_t* frontend_settings = apple_get_frontend_settings();
|
||||
setting_data_reset(frontend_settings);
|
||||
|
Loading…
x
Reference in New Issue
Block a user