mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 09:32:52 +00:00
(iOS) Many cleanups
This commit is contained in:
parent
b649099467
commit
8b7eb99140
@ -170,9 +170,6 @@ void ios_flip_game_view()
|
||||
{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[g_view display];
|
||||
|
||||
// HACK: While here, copy input structures
|
||||
ios_copy_input(&g_ios_input_data);
|
||||
});
|
||||
g_fast_forward_skips = g_is_syncing ? 0 : 3;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ static NSString* build_string_pair(NSString* stringA, NSString* stringB)
|
||||
if (indexPath.section == _firmwareSectionIndex)
|
||||
{
|
||||
NSString* item = (NSString*)[self itemForIndexPath:indexPath];
|
||||
[RetroArch_iOS displayErrorMessage:objc_getAssociatedObject(item, "OTHER") withTitle:item];
|
||||
ios_display_alert(objc_getAssociatedObject(item, "OTHER"), item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,6 @@
|
||||
|
||||
@interface RetroArch_iOS : UINavigationController<UIApplicationDelegate, UINavigationControllerDelegate>
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message;
|
||||
+ (void)displayErrorMessage:(NSString*)message withTitle:(NSString*)title;
|
||||
|
||||
+ (RetroArch_iOS*)get;
|
||||
|
||||
- (void)runGame:(NSString*)path withModule:(RAModuleInfo*)module;
|
||||
@ -33,6 +30,7 @@
|
||||
@end
|
||||
|
||||
// utility.m
|
||||
extern void ios_display_alert(NSString* message, NSString* title);
|
||||
extern void ios_clear_config_hack();
|
||||
extern bool path_make_and_check_directory(const char* path, mode_t mode, int amode);
|
||||
extern NSString* ios_get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue);
|
||||
|
@ -115,7 +115,7 @@
|
||||
}
|
||||
}
|
||||
else
|
||||
[RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Browsed path is not a directory: %@", _path]];
|
||||
ios_display_alert([NSString stringWithFormat:@"Browsed path is not a directory: %@", _path], 0);
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
@ -129,8 +129,8 @@
|
||||
else
|
||||
{
|
||||
if (access(_path.UTF8String, R_OK | W_OK | X_OK))
|
||||
[RetroArch_iOS displayErrorMessage:@"The directory containing the selected file has limited permissions. This may "
|
||||
"prevent zipped games from loading, and will cause some cores to not function."];
|
||||
ios_display_alert(@"The directory containing the selected file has limited permissions. This may "
|
||||
"prevent zipped games from loading, and will cause some cores to not function.", 0);
|
||||
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
@ -199,7 +199,7 @@
|
||||
if (info && info.data)
|
||||
[RetroArch_iOS.get pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:info] animated:YES];
|
||||
else
|
||||
[RetroArch_iOS displayErrorMessage:@"No information available."];
|
||||
ios_display_alert(@"No information available.", 0);
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
@ -125,6 +125,9 @@ static void btpad_ps3_packet_handler(struct btpad_ps3_data* device, uint8_t pack
|
||||
}
|
||||
|
||||
memcpy(device->data, packet, size);
|
||||
g_current_input_data.pad_buttons[device->slot] = btpad_ps3_get_buttons(device);
|
||||
for (int i = 0; i < 4; i ++)
|
||||
g_current_input_data.pad_axis[device->slot][i] = btpad_ps3_get_axis(device, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,30 +82,34 @@ static void btpad_wii_packet_handler(struct wiimote_t* device, uint8_t packet_ty
|
||||
case WM_RPT_BTN:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_READ:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device, WM_RPT_READ, msg + 5, ((msg[2] & 0xF0) >> 4) + 1);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_CTRL_STATUS:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device,WM_RPT_CTRL_STATUS,msg,-1);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_BTN_EXP:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handle_expansion(device, msg+2);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_current_input_data.pad_buttons[device->unid] = btpad_wii_get_buttons(device);
|
||||
for (int i = 0; i < 4; i ++)
|
||||
g_current_input_data.pad_axis[device->unid][i] = btpad_wii_get_axis(device, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,10 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#include "input/input_common.h"
|
||||
#include "ios_input.h"
|
||||
#include "general.h"
|
||||
@ -22,6 +25,215 @@
|
||||
extern const rarch_joypad_driver_t ios_joypad;
|
||||
static const rarch_joypad_driver_t* const g_joydriver = &ios_joypad;
|
||||
|
||||
ios_input_data_t g_current_input_data;
|
||||
ios_input_data_t g_polled_input_data;
|
||||
|
||||
static const struct rarch_key_map rarch_key_map_hidusage[];
|
||||
|
||||
// Main thread interface
|
||||
static bool icade_enabled;
|
||||
static uint32_t icade_buttons;
|
||||
|
||||
static void handle_icade_event(unsigned keycode)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
bool up;
|
||||
int button;
|
||||
} icade_map[0x20] =
|
||||
{
|
||||
{ false, -1 }, { false, -1 }, { false, -1 }, { false, -1 }, // 0
|
||||
{ false, 2 }, { false, -1 }, { true , 3 }, { false, 3 }, // 4
|
||||
{ true , 0 }, { true, 5 }, { true , 7 }, { false, 8 }, // 8
|
||||
{ false, 6 }, { false, 9 }, { false, 10 }, { false, 11 }, // C
|
||||
{ true , 6 }, { true , 9 }, { false, 7 }, { true, 10 }, // 0
|
||||
{ true , 2 }, { true , 8 }, { false, -1 }, { true , 4 }, // 4
|
||||
{ false, 5 }, { true , 11 }, { false, 0 }, { false, 1 }, // 8
|
||||
{ false, 4 }, { true , 1 }, { false, -1 }, { false, -1 } // C
|
||||
};
|
||||
|
||||
if (icade_enabled && (keycode < 0x20) && (icade_map[keycode].button >= 0))
|
||||
{
|
||||
const int button = icade_map[keycode].button;
|
||||
|
||||
if (icade_map[keycode].up)
|
||||
icade_buttons &= ~(1 << button);
|
||||
else
|
||||
icade_buttons |= (1 << button);
|
||||
}
|
||||
}
|
||||
|
||||
void ios_input_enable_icade(bool on)
|
||||
{
|
||||
icade_enabled = on;
|
||||
icade_buttons = 0;
|
||||
}
|
||||
|
||||
void ios_input_handle_key_event(unsigned keycode, bool down)
|
||||
{
|
||||
if (icade_enabled)
|
||||
handle_icade_event(keycode);
|
||||
else if (keycode < MAX_KEYS)
|
||||
g_current_input_data.keys[keycode] = down;
|
||||
}
|
||||
|
||||
// Game thread interface
|
||||
static bool ios_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)];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ios_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);
|
||||
}
|
||||
|
||||
// Exported input driver
|
||||
static void *ios_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)
|
||||
{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
memcpy(&g_polled_input_data, &g_current_input_data, sizeof(ios_input_data_t));
|
||||
|
||||
for (int i = 0; i != g_polled_input_data.touch_count; i ++)
|
||||
{
|
||||
input_translate_coord_viewport(g_polled_input_data.touches[i].screen_x, g_polled_input_data.touches[i].screen_y,
|
||||
&g_polled_input_data.touches[i].fixed_x, &g_polled_input_data.touches[i].fixed_y,
|
||||
&g_polled_input_data.touches[i].full_x, &g_polled_input_data.touches[i].full_y);
|
||||
}
|
||||
|
||||
input_joypad_poll(g_joydriver);
|
||||
});
|
||||
}
|
||||
|
||||
static int16_t ios_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;
|
||||
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
return input_joypad_analog(g_joydriver, port, index, id, binds[port]);
|
||||
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
return ios_key_pressed(id);
|
||||
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
{
|
||||
const bool want_full = device == RARCH_DEVICE_POINTER_SCREEN;
|
||||
|
||||
if (index < g_polled_input_data.touch_count && index < MAX_TOUCHES)
|
||||
{
|
||||
const ios_touch_data_t* touch = &g_polled_input_data.touches[index];
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED: return 1;
|
||||
case RETRO_DEVICE_ID_POINTER_X: return want_full ? touch->full_x : touch->fixed_x;
|
||||
case RETRO_DEVICE_ID_POINTER_Y: return want_full ? touch->full_y : touch->fixed_y;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ios_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;
|
||||
}
|
||||
|
||||
static void ios_input_free_input(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void ios_input_set_keybinds(void *data, unsigned device, unsigned port,
|
||||
unsigned id, unsigned keybind_action)
|
||||
{
|
||||
(void)device;
|
||||
|
||||
if (keybind_action & (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS))
|
||||
{
|
||||
switch (device)
|
||||
{
|
||||
case DEVICE_NONE:
|
||||
break;
|
||||
case DEVICE_WIIMOTE:
|
||||
strlcpy(g_settings.input.device_names[port], "Wiimote + Classic",
|
||||
sizeof(g_settings.input.device_names[port]));
|
||||
g_settings.input.device[port] = device;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_B].joykey = 22;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_Y].joykey = 21;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_SELECT].joykey = 28;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_START].joykey = 26;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_UP].joykey = 16;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = 30;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = 17;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = 31;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_A].joykey = 20;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_X].joykey = 19;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L].joykey = 29;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R].joykey = 25;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L2].joykey = 23;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R2].joykey = 18;
|
||||
g_settings.input.binds[port][RARCH_MENU_TOGGLE].joykey = 27;
|
||||
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
|
||||
break;
|
||||
case DEVICE_SIXAXIS:
|
||||
strlcpy(g_settings.input.device_names[port], "SixAxis/DualShock3",
|
||||
sizeof(g_settings.input.device_names[port]));
|
||||
g_settings.input.device[port] = device;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_B].joykey = 14;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_Y].joykey = 15;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_SELECT].joykey = 0;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_START].joykey = 3;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_UP].joykey = 4;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = 6;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = 7;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = 5;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_A].joykey = 13;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_X].joykey = 12;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L].joykey = 10;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R].joykey = 11;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L2].joykey = 8;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R2].joykey = 9;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].joykey = 1;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].joykey = 2;
|
||||
g_settings.input.binds[port][RARCH_MENU_TOGGLE].joykey = 16;
|
||||
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
|
||||
// Key table
|
||||
#include "keycode.h"
|
||||
static const struct rarch_key_map rarch_key_map_hidusage[] = {
|
||||
@ -166,158 +378,4 @@ static const struct rarch_key_map rarch_key_map_hidusage[] = {
|
||||
// RETROK_EURO },
|
||||
// RETROK_UNDO },
|
||||
{ 0, RETROK_UNKNOWN }
|
||||
};
|
||||
|
||||
ios_input_data_t g_ios_input_data;
|
||||
|
||||
// Non-exported helpers
|
||||
static bool ios_key_pressed(enum retro_key key)
|
||||
{
|
||||
if ((int)key >= 0 && key < RETROK_LAST)
|
||||
return g_ios_input_data.keys[input_translate_rk_to_keysym(key)];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ios_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);
|
||||
}
|
||||
|
||||
// Exported input driver
|
||||
static void *ios_input_init(void)
|
||||
{
|
||||
input_init_keyboard_lut(rarch_key_map_hidusage);
|
||||
memset(&g_ios_input_data, 0, sizeof(g_ios_input_data));
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
static void ios_input_poll(void *data)
|
||||
{
|
||||
for (int i = 0; i != g_ios_input_data.touch_count; i ++)
|
||||
{
|
||||
input_translate_coord_viewport(g_ios_input_data.touches[i].screen_x, g_ios_input_data.touches[i].screen_y,
|
||||
&g_ios_input_data.touches[i].fixed_x, &g_ios_input_data.touches[i].fixed_y,
|
||||
&g_ios_input_data.touches[i].full_x, &g_ios_input_data.touches[i].full_y);
|
||||
}
|
||||
|
||||
input_joypad_poll(g_joydriver);
|
||||
}
|
||||
|
||||
static int16_t ios_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;
|
||||
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
return input_joypad_analog(g_joydriver, port, index, id, binds[port]);
|
||||
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
return ios_key_pressed(id);
|
||||
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
{
|
||||
const bool want_full = device == RARCH_DEVICE_POINTER_SCREEN;
|
||||
|
||||
if (index < g_ios_input_data.touch_count && index < MAX_TOUCHES)
|
||||
{
|
||||
const ios_touch_data_t* touch = &g_ios_input_data.touches[index];
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED: return 1;
|
||||
case RETRO_DEVICE_ID_POINTER_X: return want_full ? touch->full_x : touch->fixed_x;
|
||||
case RETRO_DEVICE_ID_POINTER_Y: return want_full ? touch->full_y : touch->fixed_y;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ios_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;
|
||||
}
|
||||
|
||||
static void ios_input_free_input(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void ios_input_set_keybinds(void *data, unsigned device, unsigned port,
|
||||
unsigned id, unsigned keybind_action)
|
||||
{
|
||||
(void)device;
|
||||
|
||||
if (keybind_action & (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS))
|
||||
{
|
||||
switch (device)
|
||||
{
|
||||
case DEVICE_NONE:
|
||||
break;
|
||||
case DEVICE_WIIMOTE:
|
||||
strlcpy(g_settings.input.device_names[port], "Wiimote + Classic",
|
||||
sizeof(g_settings.input.device_names[port]));
|
||||
g_settings.input.device[port] = device;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_B].joykey = 22;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_Y].joykey = 21;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_SELECT].joykey = 28;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_START].joykey = 26;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_UP].joykey = 16;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = 30;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = 17;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = 31;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_A].joykey = 20;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_X].joykey = 19;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L].joykey = 29;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R].joykey = 25;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L2].joykey = 23;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R2].joykey = 18;
|
||||
g_settings.input.binds[port][RARCH_MENU_TOGGLE].joykey = 27;
|
||||
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
|
||||
break;
|
||||
case DEVICE_SIXAXIS:
|
||||
strlcpy(g_settings.input.device_names[port], "SixAxis/DualShock3",
|
||||
sizeof(g_settings.input.device_names[port]));
|
||||
g_settings.input.device[port] = device;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_B].joykey = 14;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_Y].joykey = 15;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_SELECT].joykey = 0;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_START].joykey = 3;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_UP].joykey = 4;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = 6;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = 7;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = 5;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_A].joykey = 13;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_X].joykey = 12;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L].joykey = 10;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R].joykey = 11;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L2].joykey = 8;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R2].joykey = 9;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_L3].joykey = 1;
|
||||
g_settings.input.binds[port][RETRO_DEVICE_ID_JOYPAD_R3].joykey = 2;
|
||||
g_settings.input.binds[port][RARCH_MENU_TOGGLE].joykey = 16;
|
||||
g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
};
|
||||
};
|
@ -39,9 +39,11 @@ typedef struct
|
||||
int16_t pad_axis[MAX_PADS][4];
|
||||
} ios_input_data_t;
|
||||
|
||||
extern ios_input_data_t g_ios_input_data;
|
||||
extern ios_input_data_t g_current_input_data; //< Main thread data
|
||||
extern ios_input_data_t g_polled_input_data; //< Game thread data
|
||||
|
||||
// Defined in main.m, must be called on the emu thread in a dispatch_sync block
|
||||
void ios_copy_input(ios_input_data_t* data);
|
||||
// Main thread only
|
||||
void ios_input_enable_icade(bool on);
|
||||
void ios_input_handle_key_event(unsigned keycode, bool down);
|
||||
|
||||
#endif
|
||||
|
@ -41,7 +41,7 @@ static bool ios_joypad_button(unsigned port, uint16_t joykey)
|
||||
if (GET_HAT_DIR(joykey))
|
||||
return false;
|
||||
else // Check the button
|
||||
return (port < MAX_PADS && joykey < 32) ? (g_ios_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false;
|
||||
return (port < MAX_PADS && joykey < 32) ? (g_polled_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false;
|
||||
}
|
||||
|
||||
static int16_t ios_joypad_axis(unsigned port, uint32_t joyaxis)
|
||||
@ -52,12 +52,12 @@ static int16_t ios_joypad_axis(unsigned port, uint32_t joyaxis)
|
||||
int16_t val = 0;
|
||||
if (AXIS_NEG_GET(joyaxis) < 4)
|
||||
{
|
||||
val = g_ios_input_data.pad_axis[AXIS_NEG_GET(joyaxis)];
|
||||
val = g_polled_input_data.pad_axis[AXIS_NEG_GET(joyaxis)];
|
||||
val = (val < 0) ? val : 0;
|
||||
}
|
||||
else if(AXIS_POS_GET(joyaxis) < 4)
|
||||
{
|
||||
val = g_ios_input_data.pad_axis[AXIS_POS_GET(joyaxis)];
|
||||
val = g_polled_input_data.pad_axis[AXIS_POS_GET(joyaxis)];
|
||||
val = (val > 0) ? val : 0;
|
||||
}
|
||||
|
||||
|
@ -30,76 +30,27 @@
|
||||
|
||||
//#define HAVE_DEBUG_FILELOG
|
||||
|
||||
static ios_input_data_t g_input_data;
|
||||
|
||||
static bool enable_btstack;
|
||||
static bool use_icade;
|
||||
static uint32_t icade_buttons;
|
||||
|
||||
// Input helpers
|
||||
void ios_copy_input(ios_input_data_t* data)
|
||||
{
|
||||
// Call only from main thread
|
||||
memcpy(data, &g_input_data, sizeof(g_input_data));
|
||||
|
||||
for (int i = 0; i < MAX_PADS; i ++)
|
||||
{
|
||||
data->pad_buttons[i] = btpad_get_buttons(i) | (((i == 0) && use_icade) ? icade_buttons : 0);
|
||||
|
||||
for (int j = 0; j < 4; j ++)
|
||||
data->pad_axis[i][j] = btpad_get_axis(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
// Input helpers: This is kept here because it needs objective-c
|
||||
static void handle_touch_event(NSArray* touches)
|
||||
{
|
||||
const int numTouches = [touches count];
|
||||
const float scale = [[UIScreen mainScreen] scale];
|
||||
|
||||
g_input_data.touch_count = 0;
|
||||
g_current_input_data.touch_count = 0;
|
||||
|
||||
for(int i = 0; i != numTouches && g_input_data.touch_count < MAX_TOUCHES; i ++)
|
||||
for(int i = 0; i != numTouches && g_current_input_data.touch_count < MAX_TOUCHES; i ++)
|
||||
{
|
||||
UITouch* touch = [touches objectAtIndex:i];
|
||||
const CGPoint coord = [touch locationInView:touch.view];
|
||||
|
||||
if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled)
|
||||
{
|
||||
g_input_data.touches[g_input_data.touch_count ].screen_x = coord.x * scale;
|
||||
g_input_data.touches[g_input_data.touch_count ++].screen_y = coord.y * scale;
|
||||
g_current_input_data.touches[g_current_input_data.touch_count ].screen_x = coord.x * scale;
|
||||
g_current_input_data.touches[g_current_input_data.touch_count ++].screen_y = coord.y * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_icade_event(unsigned keycode)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
bool up;
|
||||
int button;
|
||||
} icade_map[0x20] =
|
||||
{
|
||||
{ false, -1 }, { false, -1 }, { false, -1 }, { false, -1 }, // 0
|
||||
{ false, 2 }, { false, -1 }, { true , 3 }, { false, 3 }, // 4
|
||||
{ true , 0 }, { true, 5 }, { true , 7 }, { false, 8 }, // 8
|
||||
{ false, 6 }, { false, 9 }, { false, 10 }, { false, 11 }, // C
|
||||
{ true , 6 }, { true , 9 }, { false, 7 }, { true, 10 }, // 0
|
||||
{ true , 2 }, { true , 8 }, { false, -1 }, { true , 4 }, // 4
|
||||
{ false, 5 }, { true , 11 }, { false, 0 }, { false, 1 }, // 8
|
||||
{ false, 4 }, { true , 1 }, { false, -1 }, { false, -1 } // C
|
||||
};
|
||||
|
||||
if ((keycode < 0x20) && (icade_map[keycode].button >= 0))
|
||||
{
|
||||
const int button = icade_map[keycode].button;
|
||||
|
||||
if (icade_map[keycode].up)
|
||||
icade_buttons &= ~(1 << button);
|
||||
else
|
||||
icade_buttons |= (1 << button);
|
||||
}
|
||||
}
|
||||
|
||||
@interface RApplication : UIApplication
|
||||
@end
|
||||
|
||||
@ -121,14 +72,7 @@ static void handle_icade_event(unsigned keycode)
|
||||
int eventType = eventMem ? *(int*)&eventMem[8] : 0;
|
||||
|
||||
if (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP)
|
||||
{
|
||||
uint16_t key = *(uint16_t*)&eventMem[0x3C];
|
||||
|
||||
if (!use_icade && key < MAX_KEYS)
|
||||
g_input_data.keys[key] = (eventType == GSEVENT_TYPE_KEYDOWN);
|
||||
else if (eventType == GSEVENT_TYPE_KEYDOWN)
|
||||
handle_icade_event(key);
|
||||
}
|
||||
ios_input_handle_key_event(*(uint16_t*)&eventMem[0x3C], eventType == GSEVENT_TYPE_KEYDOWN);
|
||||
|
||||
CFBridgingRelease(eventMem);
|
||||
}
|
||||
@ -204,21 +148,6 @@ static void event_reload_config(void* userdata)
|
||||
RAModuleInfo* _module;
|
||||
}
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message
|
||||
{
|
||||
[RetroArch_iOS displayErrorMessage:message withTitle:@"RetroArch"];
|
||||
}
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message withTitle:(NSString*)title
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title
|
||||
message:message
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
+ (RetroArch_iOS*)get
|
||||
{
|
||||
return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate];
|
||||
@ -240,9 +169,9 @@ static void event_reload_config(void* userdata)
|
||||
self.systemConfigPath = [self.systemDirectory stringByAppendingPathComponent:@"frontend.cfg"];
|
||||
|
||||
if (!path_make_and_check_directory(self.documentsDirectory.UTF8String, 0755, R_OK | W_OK | X_OK))
|
||||
[RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory]];
|
||||
ios_display_alert([NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory], 0);
|
||||
else if (!path_make_and_check_directory(self.systemDirectory.UTF8String, 0755, R_OK | W_OK | X_OK))
|
||||
[RetroArch_iOS displayErrorMessage:[NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory]];
|
||||
ios_display_alert([NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory], 0);
|
||||
else
|
||||
{
|
||||
[self pushViewController:[RADirectoryList directoryListAtBrowseRoot] animated:YES];
|
||||
@ -251,7 +180,7 @@ static void event_reload_config(void* userdata)
|
||||
|
||||
// Warn if there are no cores present
|
||||
if ([RAModuleInfo getModules].count == 0)
|
||||
[RetroArch_iOS displayErrorMessage:@"No libretro cores were found. You will not be able to play any games."];
|
||||
ios_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0);
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
@ -357,7 +286,7 @@ static void event_reload_config(void* userdata)
|
||||
- (void)rarchExited:(BOOL)successful
|
||||
{
|
||||
if (!successful)
|
||||
[RetroArch_iOS displayErrorMessage:@"Failed to load game."];
|
||||
ios_display_alert(@"Failed to load game.", 0);
|
||||
|
||||
if (_isRunning)
|
||||
{
|
||||
@ -409,10 +338,9 @@ static void event_reload_config(void* userdata)
|
||||
}
|
||||
|
||||
//
|
||||
config_get_bool(conf, "ios_use_icade", &use_icade);
|
||||
config_get_bool(conf, "ios_use_btstack", &enable_btstack);
|
||||
|
||||
btstack_set_poweron(enable_btstack);
|
||||
bool val;
|
||||
ios_input_enable_icade(config_get_bool(conf, "ios_use_icade", &val) && val);
|
||||
btstack_set_poweron(config_get_bool(conf, "ios_use_btstack", &val) && val);
|
||||
|
||||
config_file_free(conf);
|
||||
}
|
||||
|
@ -747,9 +747,6 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
||||
|
||||
- (void)checkInput
|
||||
{
|
||||
ios_input_data_t data;
|
||||
ios_copy_input(&data);
|
||||
|
||||
// Keyboard
|
||||
static const struct
|
||||
{
|
||||
@ -808,7 +805,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
||||
|
||||
for (int i = 0; ios_key_name_map[i].hid_id; i++)
|
||||
{
|
||||
if (data.keys[ios_key_name_map[i].hid_id])
|
||||
if (g_current_input_data.keys[ios_key_name_map[i].hid_id])
|
||||
{
|
||||
_value.msubValues[0] = [NSString stringWithUTF8String:ios_key_name_map[i].keyname];
|
||||
[self finish];
|
||||
@ -817,9 +814,9 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
||||
}
|
||||
|
||||
// Pad Buttons
|
||||
for (int i = 0; data.pad_buttons[_value.player] && i < sizeof(data.pad_buttons[_value.player]) * 8; i++)
|
||||
for (int i = 0; g_current_input_data.pad_buttons[_value.player] && i < sizeof(g_current_input_data.pad_buttons[_value.player]) * 8; i++)
|
||||
{
|
||||
if (data.pad_buttons[_value.player] & (1 << i))
|
||||
if (g_current_input_data.pad_buttons[_value.player] & (1 << i))
|
||||
{
|
||||
_value.msubValues[1] = [NSString stringWithFormat:@"%d", i];
|
||||
[self finish];
|
||||
@ -830,7 +827,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
||||
// Pad Axis
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value = data.pad_axis[_value.player][i];
|
||||
int16_t value = g_current_input_data.pad_axis[_value.player][i];
|
||||
|
||||
if (abs(value) > 0x1000)
|
||||
{
|
||||
|
@ -19,6 +19,16 @@
|
||||
#include "file.h"
|
||||
#import "views.h"
|
||||
|
||||
void ios_display_alert(NSString* message, NSString* title)
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title ? title : @"RetroArch"
|
||||
message:message
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
// Little nudge to prevent stale values when reloading the confg file
|
||||
void ios_clear_config_hack()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user