2015-10-22 05:13:26 +00:00
|
|
|
/*
|
|
|
|
* Apple // emulator for *ix
|
|
|
|
*
|
|
|
|
* This software package is subject to the GNU General Public License
|
|
|
|
* version 3 or later (your choice) as published by the Free Software
|
|
|
|
* Foundation.
|
|
|
|
*
|
|
|
|
* Copyright 2014, 2015 Aaron Culliney
|
|
|
|
*
|
|
|
|
*/
|
2014-11-10 03:59:47 +00:00
|
|
|
|
|
|
|
#import "EmulatorJoystickController.h"
|
2014-11-30 23:35:21 +00:00
|
|
|
#import "EmulatorWindowController.h"
|
2014-11-10 03:59:47 +00:00
|
|
|
#import "common.h"
|
|
|
|
|
2014-11-30 23:35:21 +00:00
|
|
|
#import <DDHidLib/DDHidJoystick.h>
|
|
|
|
|
2014-11-10 03:59:47 +00:00
|
|
|
@interface EmulatorJoystickController()
|
2014-11-29 21:33:57 +00:00
|
|
|
@property (nonatomic, retain) NSDictionary *allJoysticks;
|
2014-11-30 23:35:21 +00:00
|
|
|
+ (EmulatorJoystickController *)sharedInstance;
|
2014-11-10 03:59:47 +00:00
|
|
|
- (void)resetJoysticks;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation EmulatorJoystickController
|
|
|
|
|
|
|
|
@synthesize allJoysticks = _allJoysticks;
|
|
|
|
|
|
|
|
+ (EmulatorJoystickController *)sharedInstance
|
|
|
|
{
|
|
|
|
static dispatch_once_t onceToken = 0L;
|
|
|
|
static EmulatorJoystickController *joystickController = nil;
|
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
|
joystickController = [[EmulatorJoystickController alloc] init];
|
|
|
|
});
|
|
|
|
return joystickController;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)init
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if (self)
|
|
|
|
{
|
2014-11-30 23:35:21 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectivityPoll:) name:(NSString *)kDrawTimerNotification object:nil];
|
2014-11-10 03:59:47 +00:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
2014-11-30 23:35:21 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
2014-11-10 03:59:47 +00:00
|
|
|
self.allJoysticks = nil;
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)resetJoysticks
|
|
|
|
{
|
2014-11-29 21:33:57 +00:00
|
|
|
for (DDHidJoystick *joystick in [self.allJoysticks allValues])
|
2014-11-10 03:59:47 +00:00
|
|
|
{
|
2014-11-29 21:33:57 +00:00
|
|
|
@try {
|
|
|
|
[joystick setDelegate:nil];
|
|
|
|
[joystick stopListening];
|
|
|
|
} @catch (NSException *e) {
|
|
|
|
// hot-plugging joysticks can cause glitches
|
|
|
|
NSLog(@"Joystick device library raised exception on close : %@", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NSArray *joysticks = [DDHidJoystick allJoysticks];
|
|
|
|
NSMutableDictionary *allJoysticks = [NSMutableDictionary dictionary];
|
|
|
|
for (DDHidJoystick *joystick in joysticks) {
|
|
|
|
NSString *key =[NSString stringWithFormat:@"%@-%@-%@", [joystick manufacturer], [joystick serialNumber], [joystick transport]];
|
|
|
|
[allJoysticks setObject:joystick forKey:key];
|
2014-11-10 03:59:47 +00:00
|
|
|
}
|
2014-11-29 21:33:57 +00:00
|
|
|
self.allJoysticks = allJoysticks;
|
2014-11-10 03:59:47 +00:00
|
|
|
dispatch_async(dispatch_get_main_queue(), ^ {
|
2014-11-29 21:33:57 +00:00
|
|
|
for (DDHidJoystick *joystick in [self.allJoysticks allValues])
|
2014-11-10 03:59:47 +00:00
|
|
|
{
|
|
|
|
NSLog(@"found joystick : '%@' '%@' '%@' %@", [joystick manufacturer], [joystick serialNumber], [joystick transport], joystick);
|
2014-11-29 21:33:57 +00:00
|
|
|
@try {
|
|
|
|
[joystick setDelegate:self];
|
|
|
|
[joystick startListening];
|
|
|
|
} @catch (NSException *e) {
|
|
|
|
// hot-plugging joystick can cause glitches
|
|
|
|
NSLog(@"Joystick device library raised exception on start : %@", e);
|
|
|
|
}
|
2014-11-10 03:59:47 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-11-29 21:33:57 +00:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Joystick connectivity polling
|
|
|
|
|
2014-11-30 23:35:21 +00:00
|
|
|
- (void)connectivityPoll:(NSNotification *)notification
|
2014-11-29 21:33:57 +00:00
|
|
|
{
|
2014-12-02 06:39:46 +00:00
|
|
|
static unsigned int counter = 0;
|
|
|
|
counter = (counter+1) % 60;
|
|
|
|
if (counter == 0)
|
2014-11-29 21:33:57 +00:00
|
|
|
{
|
2014-12-02 06:39:46 +00:00
|
|
|
NSArray *joysticks = [DDHidJoystick allJoysticks];
|
|
|
|
BOOL changed = ([joysticks count] != [self.allJoysticks count]);
|
|
|
|
for (DDHidJoystick *joystick in joysticks)
|
2014-11-29 21:33:57 +00:00
|
|
|
{
|
2014-12-02 06:39:46 +00:00
|
|
|
NSString *key =[NSString stringWithFormat:@"%@-%@-%@", [joystick manufacturer], [joystick serialNumber], [joystick transport]];
|
|
|
|
if (![self.allJoysticks objectForKey:key])
|
|
|
|
{
|
|
|
|
changed = YES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (changed)
|
|
|
|
{
|
|
|
|
[self resetJoysticks];
|
2014-11-29 21:33:57 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-02 06:39:46 +00:00
|
|
|
#ifdef KEYPAD_JOYSTICK
|
|
|
|
if (joy_mode == JOY_KPAD)
|
2014-11-29 21:33:57 +00:00
|
|
|
{
|
2014-12-02 06:39:46 +00:00
|
|
|
c_keys_handle_input(-1, 0, 0);
|
2014-11-29 21:33:57 +00:00
|
|
|
}
|
2014-12-02 06:39:46 +00:00
|
|
|
#endif
|
2014-11-29 21:33:57 +00:00
|
|
|
}
|
|
|
|
|
2014-11-10 03:59:47 +00:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark NSObject(DDHidJoystickDelegate)
|
|
|
|
|
2014-12-06 06:31:12 +00:00
|
|
|
#define DDHID_JOYSTICK_NORMALIZER ((float)JOY_RANGE/(DDHID_JOYSTICK_VALUE_MAX*2))
|
2014-11-10 03:59:47 +00:00
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick xChanged:(int)value
|
|
|
|
{
|
|
|
|
#ifdef KEYPAD_JOYSTICK
|
|
|
|
if (joy_mode == JOY_KPAD) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-04-23 21:56:05 +00:00
|
|
|
int x = (int)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
|
|
|
if (x < 0) {
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
if (x >= JOY_RANGE) {
|
|
|
|
x = JOY_RANGE-1;
|
|
|
|
}
|
|
|
|
joydriver_setAxisValue((uint8_t)x, joydriver_getAxisY());
|
2014-11-10 03:59:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick yChanged:(int)value
|
|
|
|
{
|
|
|
|
#ifdef KEYPAD_JOYSTICK
|
|
|
|
if (joy_mode == JOY_KPAD) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-04-23 21:56:05 +00:00
|
|
|
int y = (int)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
|
|
|
if (y < 0) {
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
if (y >= JOY_RANGE) {
|
|
|
|
y = JOY_RANGE-1;
|
|
|
|
}
|
|
|
|
joydriver_setAxisValue(joydriver_getAxisX(), (uint8_t)y);
|
2014-11-10 03:59:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick otherAxis:(unsigned)otherAxis valueChanged:(int)value
|
|
|
|
{
|
|
|
|
// NOOP ...
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick povNumber:(unsigned)povNumber valueChanged:(int)value
|
|
|
|
{
|
|
|
|
// NOOP ...
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick buttonDown:(unsigned int)buttonNumber
|
|
|
|
{
|
|
|
|
#ifdef KEYPAD_JOYSTICK
|
|
|
|
if (joy_mode == JOY_KPAD) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// sample buttons only if apple keys aren't pressed. keys get set to 0xff, and js buttons are set to 0x80.
|
|
|
|
if ((buttonNumber == 0x01) && !(joy_button0 & 0x7f)) {
|
|
|
|
joy_button0 = 0x80;
|
|
|
|
}
|
|
|
|
if ((buttonNumber == 0x02) && !(joy_button1 & 0x7f)) {
|
|
|
|
joy_button1 = 0x80;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)ddhidJoystick:(DDHidJoystick *)joystick buttonUp:(unsigned int)buttonNumber
|
|
|
|
{
|
|
|
|
#ifdef KEYPAD_JOYSTICK
|
|
|
|
if (joy_mode == JOY_KPAD) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// sample buttons only if apple keys aren't pressed. keys get set to 0xff, and js buttons are set to 0x80.
|
|
|
|
if ((buttonNumber == 0x01) && !(joy_button0 & 0x7f)) {
|
|
|
|
joy_button0 = 0x0;
|
|
|
|
}
|
|
|
|
if ((buttonNumber == 0x02) && !(joy_button1 & 0x7f)) {
|
|
|
|
joy_button1 = 0x0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@end
|