(Apple) Add keyboard input support for OSX

This commit is contained in:
meancoot 2013-07-07 16:01:58 -04:00
parent 7a4085b67f
commit 78acc25931
14 changed files with 112 additions and 60 deletions

View File

@ -42,6 +42,6 @@
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<string>RApplication</string>
</dict>
</plist>

View File

@ -81,6 +81,16 @@ static float g_screen_scale = 1.0f;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// Stop the annoying sound when pressing a key
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)keyDown:(NSEvent*)theEvent
{
}
#elif defined(IOS) // < iOS Pause menu and lifecycle
- (id)init
{

View File

@ -18,18 +18,39 @@
#include <dispatch/dispatch.h>
#include "input/input_common.h"
#include "ios_input.h"
#include "apple_input.h"
#include "general.h"
#include "driver.h"
#ifdef IOS
extern const rarch_joypad_driver_t ios_joypad;
static const rarch_joypad_driver_t* const g_joydriver = &ios_joypad;
#else
static const rarch_joypad_driver_t* const g_joydriver = 0;
#endif
ios_input_data_t g_current_input_data;
ios_input_data_t g_polled_input_data;
apple_input_data_t g_current_input_data;
apple_input_data_t g_polled_input_data;
static const struct rarch_key_map rarch_key_map_hidusage[];
#ifdef OSX // Taken from https://github.com/depp/keycode, check keycode.h for license
const unsigned char MAC_NATIVE_TO_HID[128] = {
4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21,
28, 23, 30, 31, 32, 33, 35, 34, 46, 38, 36, 45, 37, 39, 48, 18,
24, 47, 12, 19, 40, 15, 13, 52, 14, 51, 49, 54, 56, 17, 16, 55,
43, 44, 53, 42,255, 41,231,227,225, 57,226,224,229,230,228,255,
108, 99,255, 85,255, 87,255, 83,255,255,255, 84, 88,255, 86,109,
110,103, 98, 89, 90, 91, 92, 93, 94, 95,111, 96, 97,255,255,255,
62, 63, 64, 60, 65, 66,255, 68,255,104,107,105,255, 67,255, 69,
255,106,117, 74, 75, 76, 61, 77, 59, 78, 58, 80, 79, 81, 82,255
};
#define HIDKEY(X) (X < 128) ? MAC_NATIVE_TO_HID[X] : 0
#else
#define HIDKEY(X) X
#endif
// Main thread interface
static bool icade_enabled;
static uint32_t icade_buttons;
@ -63,14 +84,16 @@ static void handle_icade_event(unsigned keycode)
}
}
void ios_input_enable_icade(bool on)
void apple_input_enable_icade(bool on)
{
icade_enabled = on;
icade_buttons = 0;
}
void ios_input_handle_key_event(unsigned keycode, bool down)
void apple_input_handle_key_event(unsigned keycode, bool down)
{
keycode = HIDKEY(keycode);
if (icade_enabled)
handle_icade_event(keycode);
else if (keycode < MAX_KEYS)
@ -78,7 +101,7 @@ void ios_input_handle_key_event(unsigned keycode, bool down)
}
// Game thread interface
static bool ios_key_pressed(enum retro_key key)
static bool apple_key_pressed(enum retro_key key)
{
if ((int)key >= 0 && key < RETROK_LAST)
return g_polled_input_data.keys[input_translate_rk_to_keysym(key)];
@ -86,23 +109,23 @@ static bool ios_key_pressed(enum retro_key key)
return false;
}
static bool ios_is_pressed(unsigned port_num, const struct retro_keybind *binds, unsigned key)
static bool apple_is_pressed(unsigned port_num, const struct retro_keybind *binds, unsigned key)
{
return ios_key_pressed(binds[key].key) || input_joypad_pressed(g_joydriver, port_num, binds, key);
return apple_key_pressed(binds[key].key) || input_joypad_pressed(g_joydriver, port_num, binds, key);
}
// Exported input driver
static void *ios_input_init(void)
static void *apple_input_init(void)
{
input_init_keyboard_lut(rarch_key_map_hidusage);
memset(&g_polled_input_data, 0, sizeof(g_polled_input_data));
return (void*)-1;
}
static void ios_input_poll(void *data)
static void apple_input_poll(void *data)
{
dispatch_sync(dispatch_get_main_queue(), ^{
memcpy(&g_polled_input_data, &g_current_input_data, sizeof(ios_input_data_t));
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 ++)
{
@ -115,18 +138,18 @@ static void ios_input_poll(void *data)
});
}
static int16_t ios_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id)
static int16_t apple_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id)
{
switch (device)
{
case RETRO_DEVICE_JOYPAD:
return (id < RARCH_BIND_LIST_END) ? ios_is_pressed(port, binds[port], id) : false;
return (id < RARCH_BIND_LIST_END) ? apple_is_pressed(port, binds[port], id) : false;
case RETRO_DEVICE_ANALOG:
return input_joypad_analog(g_joydriver, port, index, id, binds[port]);
case RETRO_DEVICE_KEYBOARD:
return ios_key_pressed(id);
return apple_key_pressed(id);
case RETRO_DEVICE_POINTER:
case RARCH_DEVICE_POINTER_SCREEN:
@ -135,7 +158,7 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u
if (index < g_polled_input_data.touch_count && index < MAX_TOUCHES)
{
const ios_touch_data_t* touch = &g_polled_input_data.touches[index];
const apple_touch_data_t* touch = &g_polled_input_data.touches[index];
switch (id)
{
@ -153,22 +176,23 @@ static int16_t ios_input_state(void *data, const struct retro_keybind **binds, u
}
}
static bool ios_bind_button_pressed(void *data, int key)
static bool apple_bind_button_pressed(void *data, int key)
{
const struct retro_keybind *binds = g_settings.input.binds[0];
return (key >= 0 && key < RARCH_BIND_LIST_END) ? ios_is_pressed(0, binds, key) : false;
return (key >= 0 && key < RARCH_BIND_LIST_END) ? apple_is_pressed(0, binds, key) : false;
}
static void ios_input_free_input(void *data)
static void apple_input_free_input(void *data)
{
(void)data;
}
static void ios_input_set_keybinds(void *data, unsigned device, unsigned port,
static void apple_input_set_keybinds(void *data, unsigned device, unsigned port,
unsigned id, unsigned keybind_action)
{
(void)device;
#ifdef IOS
if (keybind_action & (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS))
{
switch (device)
@ -221,16 +245,17 @@ static void ios_input_set_keybinds(void *data, unsigned device, unsigned port,
break;
}
}
#endif
}
const input_driver_t input_ios = {
ios_input_init,
ios_input_poll,
ios_input_state,
ios_bind_button_pressed,
ios_input_free_input,
ios_input_set_keybinds,
"ios_input",
const input_driver_t input_apple = {
apple_input_init,
apple_input_poll,
apple_input_state,
apple_bind_button_pressed,
apple_input_free_input,
apple_input_set_keybinds,
"apple_input",
};

View File

@ -13,8 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __IOS_RARCH_INPUT_H__
#define __IOS_RARCH_INPUT_H__
#ifndef __APPLE_RARCH_INPUT_H__
#define __APPLE_RARCH_INPUT_H__
// Input responder
#define MAX_TOUCHES 16
@ -26,24 +26,24 @@ typedef struct
int16_t screen_x, screen_y;
int16_t fixed_x, fixed_y;
int16_t full_x, full_y;
} ios_touch_data_t;
} apple_touch_data_t;
typedef struct
{
ios_touch_data_t touches[MAX_TOUCHES];
apple_touch_data_t touches[MAX_TOUCHES];
uint32_t touch_count;
uint32_t keys[MAX_KEYS];
uint32_t pad_buttons[MAX_PADS];
int16_t pad_axis[MAX_PADS][4];
} ios_input_data_t;
} apple_input_data_t;
extern ios_input_data_t g_current_input_data; //< Main thread data
extern ios_input_data_t g_polled_input_data; //< Game thread data
extern apple_input_data_t g_current_input_data; //< Main thread data
extern apple_input_data_t g_polled_input_data; //< Game thread data
// Main thread only
void ios_input_enable_icade(bool on);
void ios_input_handle_key_event(unsigned keycode, bool down);
void apple_input_enable_icade(bool on);
void apple_input_handle_key_event(unsigned keycode, bool down);
#endif

View File

@ -19,10 +19,10 @@
#import "RetroArch_Apple.h"
#include "rarch_wrapper.h"
#include "apple_input.h"
#ifdef IOS
#import "views.h"
#include "../iOS/input/ios_input.h"
#include "../iOS/input/keycode.h"
#include "../iOS/input/BTStack/btpad.h"
#include "../iOS/input/BTStack/btdynamic.h"
#include "../iOS/input/BTStack/btpad.h"
@ -30,6 +30,9 @@
#include "file.h"
#define GSEVENT_TYPE_KEYDOWN 10
#define GSEVENT_TYPE_KEYUP 11
//#define HAVE_DEBUG_FILELOG
static bool use_tv_mode;
@ -179,9 +182,6 @@ static void handle_touch_event(NSArray* touches)
@implementation RApplication
#define GSEVENT_TYPE_KEYDOWN 10
#define GSEVENT_TYPE_KEYUP 11
- (void)sendEvent:(UIEvent *)event
{
[super sendEvent:event];
@ -195,7 +195,7 @@ static void handle_touch_event(NSArray* touches)
int eventType = eventMem ? *(int*)&eventMem[8] : 0;
if (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)
ios_input_handle_key_event(*(uint16_t*)&eventMem[0x3C], eventType == GSEVENT_TYPE_KEYDOWN);
apple_input_handle_key_event(*(uint16_t*)&eventMem[0x3C], eventType == GSEVENT_TYPE_KEYDOWN);
CFBridgingRelease(eventMem);
}
@ -389,7 +389,7 @@ int main(int argc, char *argv[])
//
bool val;
ios_input_enable_icade(config_get_bool(conf, "ios_use_icade", &val) && val);
apple_input_enable_icade(config_get_bool(conf, "ios_use_icade", &val) && val);
btstack_set_poweron(config_get_bool(conf, "ios_use_btstack", &val) && val);
use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val;
@ -473,6 +473,21 @@ int main(int argc, char *argv[])
#pragma mark OSX
#ifdef OSX
@interface RApplication : NSApplication
@end
@implementation RApplication
- (void)sendEvent:(NSEvent *)event
{
[super sendEvent:event];
if (event.type == GSEVENT_TYPE_KEYDOWN || event.type == GSEVENT_TYPE_KEYUP)
apple_input_handle_key_event(event.keyCode, event.type == GSEVENT_TYPE_KEYDOWN);
}
@end
@implementation RetroArch_OSX
+ (RetroArch_OSX*)get
{
@ -492,7 +507,9 @@ int main(int argc, char *argv[])
[window.contentView setAutoresizesSubviews:YES];
RAGameView.get.frame = [window.contentView bounds];
[window.contentView addSubview:RAGameView.get];
[window.contentView addSubview:RAGameView.get];
[window makeFirstResponder:RAGameView.get];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication

View File

@ -277,7 +277,6 @@
"-DHAVE_ZLIB",
"-DWANT_MINIZ",
"-DSINC_LOWER_QUALITY",
"-DHAVE_NULLINPUT",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@ -333,7 +332,6 @@
"-DHAVE_ZLIB",
"-DWANT_MINIZ",
"-DSINC_LOWER_QUALITY",
"-DHAVE_NULLINPUT",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;

View File

@ -14,7 +14,7 @@
*/
#include "input/input_common.h"
#include "ios_input.h"
#include "../../RetroArch/apple_input.h"
#include "BTStack/btpad.h"
#include "general.h"

View File

@ -16,8 +16,8 @@
#import "../RetroArch/RetroArch_Apple.h"
#import "views.h"
#include "input/ios_input.h"
#include "input/keycode.h"
#include "../RetroArch/apple_input.h"
#include "../RetroArch/keycode.h"
#include "input/BTStack/btdynamic.h"
#include "input/BTStack/btpad.h"

View File

@ -73,7 +73,7 @@ enum
INPUT_WII,
INPUT_XINPUT,
INPUT_LINUXRAW,
INPUT_IOS,
INPUT_APPLE,
INPUT_QNX,
INPUT_NULL
};
@ -160,8 +160,8 @@ enum
#define INPUT_DEFAULT_DRIVER INPUT_WII
#elif defined(HAVE_XVIDEO)
#define INPUT_DEFAULT_DRIVER INPUT_X
#elif defined(IOS)
#define INPUT_DEFAULT_DRIVER INPUT_IOS
#elif defined(IOS) || defined(OSX)
#define INPUT_DEFAULT_DRIVER INPUT_APPLE
#elif defined(__BLACKBERRY_QNX__)
#define INPUT_DEFAULT_DRIVER INPUT_QNX
#else

View File

@ -155,8 +155,8 @@ static const input_driver_t *input_drivers[] = {
#if defined(__linux__) && !defined(ANDROID)
&input_linuxraw,
#endif
#ifdef IOS
&input_ios,
#if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds
&input_apple,
#endif
#ifdef __BLACKBERRY_QNX__
&input_qnx,

View File

@ -525,7 +525,7 @@ extern const input_driver_t input_xenon360;
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_apple;
extern const input_driver_t input_qnx;
extern const input_driver_t input_null;

View File

@ -254,8 +254,9 @@ INPUT
#elif defined(ANDROID)
#include "../android/native/jni/input_autodetect.c"
#include "../android/native/jni/input_android.c"
#elif defined(IOS)
#include "../apple/iOS/input/ios_input.c"
#elif defined(IOS) || defined(OSX)
#include "../apple/RetroArch/apple_input.c"
#ifdef IOS
#include "../apple/iOS/input/ios_joypad.c"
#include "../apple/iOS/input/BTStack/btdynamic.c"
#include "../apple/iOS/input/BTStack/wiimote.c"
@ -263,6 +264,7 @@ INPUT
#include "../apple/iOS/input/BTStack/btpad_ps3.c"
#include "../apple/iOS/input/BTStack/btpad_wii.c"
#include "../apple/iOS/input/BTStack/btpad_queue.c"
#endif
#elif defined(__BLACKBERRY_QNX__)
#include "../blackberry-qnx/qnx_input.c"
#endif

View File

@ -131,8 +131,8 @@ const char *config_get_default_input(void)
return "gx";
case INPUT_LINUXRAW:
return "linuxraw";
case INPUT_IOS:
return "ios_input";
case INPUT_APPLE:
return "apple_input";
case INPUT_QNX:
return "qnx_input";
case INPUT_NULL: