diff --git a/Apple2Mac/Apple2Mac/Classes/OSX/EmulatorJoystickController.m b/Apple2Mac/Apple2Mac/Classes/OSX/EmulatorJoystickController.m index b1452419..a12a9652 100644 --- a/Apple2Mac/Apple2Mac/Classes/OSX/EmulatorJoystickController.m +++ b/Apple2Mac/Apple2Mac/Classes/OSX/EmulatorJoystickController.m @@ -127,26 +127,6 @@ void gldriver_joystick_reset(void) { #pragma mark NSObject(DDHidJoystickDelegate) #define DDHID_JOYSTICK_NORMALIZER ((float)JOY_RANGE/(DDHID_JOYSTICK_VALUE_MAX*2)) -#define QUARTER_JOY (HALF_JOY_RANGE>>1) - -static inline void clampBeyondRadius(void) { - CGFloat half_x = joy_x - HALF_JOY_RANGE; - CGFloat half_y = joy_y - HALF_JOY_RANGE; - CGFloat r = sqrtf(half_x*half_x + half_y*half_y); - bool shouldClip = (r > HALF_JOY_RANGE); - if (joy_clip_to_radius && shouldClip) { - if (joy_x < HALF_JOY_RANGE) { - joy_x = (joy_x < QUARTER_JOY) ? 0.f : joy_x; - } else { - joy_x = (joy_x < HALF_JOY_RANGE+QUARTER_JOY) ? joy_x : JOY_RANGE-1; - } - if (joy_y < HALF_JOY_RANGE) { - joy_y = (joy_y < QUARTER_JOY) ? 0.f : joy_y; - } else { - joy_y = (joy_y < HALF_JOY_RANGE+QUARTER_JOY) ? joy_y : JOY_RANGE-1; - } - } -} - (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick xChanged:(int)value { @@ -156,12 +136,8 @@ static inline void clampBeyondRadius(void) { } #endif - joy_x = (uint16_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER); - if (joy_x > 0xFF) { - joy_x = 0xFF; - } - - clampBeyondRadius(); + uint8_t x = (uint8_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER); + joydriver_setAxisValue(x, joydriver_getAxisY()); } - (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick yChanged:(int)value @@ -172,12 +148,8 @@ static inline void clampBeyondRadius(void) { } #endif - joy_y = (uint16_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER); - if (joy_y > 0xFF) { - joy_y = 0xFF; - } - - clampBeyondRadius(); + uint8_t y = (uint8_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER); + joydriver_setAxisValue(joydriver_getAxisX(), y); } - (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick otherAxis:(unsigned)otherAxis valueChanged:(int)value diff --git a/src/joystick.c b/src/joystick.c index ec707997..4fbebc5a 100644 --- a/src/joystick.c +++ b/src/joystick.c @@ -253,6 +253,55 @@ void c_joystick_reset(void) #endif } +// clamps modern gamepad controller axis values to the "corners" of a traditional joystick as used on the Apple //e +static inline void clampBeyondRadius(uint8_t *x, uint8_t *y) { + float half_x = (*x) - HALF_JOY_RANGE; + float half_y = (*y) - HALF_JOY_RANGE; + float r = sqrtf(half_x*half_x + half_y*half_y); + bool shouldClip = (r > HALF_JOY_RANGE); + if (joy_clip_to_radius && shouldClip) { + if ((*x) < HALF_JOY_RANGE) { + (*x) = ((*x) < QUARTER_JOY_RANGE) ? 0.f : (*x); + } else { + (*x) = ((*x) < HALF_JOY_RANGE+QUARTER_JOY_RANGE) ? (*x) : 0xFF; + } + if ((*y) < HALF_JOY_RANGE) { + (*y) = ((*y) < QUARTER_JOY_RANGE) ? 0.f : (*y); + } else { + (*y) = ((*y) < HALF_JOY_RANGE+QUARTER_JOY_RANGE) ? (*y) : JOY_RANGE-1; + } + } +} + +void joydriver_setClampBeyondRadius(bool clamp) { + joy_clip_to_radius = clamp; +} + +void joydriver_setAxisValue(uint8_t x, uint8_t y) { + clampBeyondRadius(&x, &y); + joy_x = x; + joy_y = y; +} + +uint8_t joydriver_getAxisX(void) { + return joy_x; +} + +// return Y axis value +uint8_t joydriver_getAxisY(void) { + return joy_y; +} + +// set button 0 pressed +void joydriver_setButton0Pressed(bool pressed) { + joy_button0 = (pressed) ? 0x80 : 0x0; +} + +// set button 1 pressed +void joydriver_setButton1Pressed(bool pressed) { + joy_button1 = (pressed) ? 0x80 : 0x0; +} + #if INTERFACE_TOUCH bool (*joydriver_isTouchJoystickAvailable)(void) = NULL; void (*joydriver_setTouchJoystickEnabled)(bool enabled) = NULL; diff --git a/src/joystick.h b/src/joystick.h index e9a23b2c..5362d498 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -13,7 +13,8 @@ #define _JOYSTICK_H_ #define JOY_RANGE 0x100 -#define HALF_JOY_RANGE 0x80 +#define HALF_JOY_RANGE (JOY_RANGE>>1) +#define QUARTER_JOY_RANGE (HALF_JOY_RANGE>>1) extern uint16_t joy_x; extern uint16_t joy_y; @@ -32,6 +33,24 @@ void c_joystick_reset(void); void c_calibrate_joystick(void); #endif +// enable/disable gamepad clamping to joystick corners +void joydriver_setClampBeyondRadius(bool clamp); + +// set joystick axis values +void joydriver_setAxisValue(uint8_t x, uint8_t y); + +// return X axis value +uint8_t joydriver_getAxisX(void); + +// return Y axis value +uint8_t joydriver_getAxisY(void); + +// set button 0 pressed +void joydriver_setButton0Pressed(bool pressed); + +// set button 1 pressed +void joydriver_setButton1Pressed(bool pressed); + #if INTERFACE_TOUCH typedef enum touchjoy_variant_t {