Improved analog stick controls in both ports. Affects #34?

This commit is contained in:
Lior Halphon 2018-06-26 19:36:14 +03:00
parent 3a4ed6fd40
commit 32443a9675
4 changed files with 96 additions and 52 deletions

View File

@ -5,6 +5,9 @@
#import "GBButtons.h"
#import "NSString+StringForKey.h"
#define JOYSTICK_HIGH 0x4000
#define JOYSTICK_LOW 0x3800
@implementation GBView
{
uint32_t *image_buffers[3];
@ -12,7 +15,7 @@
BOOL mouse_hidden;
NSTrackingArea *tracking_area;
BOOL _mouseHidingEnabled;
bool enableAnalog;
bool axisActive[2];
bool underclockKeyDown;
double clockMultiplier;
NSEventModifierFlags previousModifiers;
@ -241,9 +244,6 @@
break;
default:
if (i < GB_KEY_A) {
enableAnalog = false;
}
GB_set_key_state(_gb, (GB_key_t)i, state);
break;
}
@ -258,18 +258,39 @@
NSNumber *x_axis = [mapping objectForKey:@"XAxis"];
NSNumber *y_axis = [mapping objectForKey:@"YAxis"];
if (value > 0x4000 || value < -0x4000) {
enableAnalog = true;
if (axis == [x_axis integerValue]) {
if (value > JOYSTICK_HIGH) {
axisActive[0] = true;
GB_set_key_state(_gb, GB_KEY_RIGHT, true);
GB_set_key_state(_gb, GB_KEY_LEFT, false);
}
else if (value < -JOYSTICK_HIGH) {
axisActive[0] = true;
GB_set_key_state(_gb, GB_KEY_RIGHT, false);
GB_set_key_state(_gb, GB_KEY_LEFT, true);
}
else if (axisActive[0] && value < JOYSTICK_LOW && value > -JOYSTICK_LOW) {
axisActive[0] = false;
GB_set_key_state(_gb, GB_KEY_RIGHT, false);
GB_set_key_state(_gb, GB_KEY_LEFT, false);
}
}
if (!enableAnalog) return;
if (x_axis && [x_axis integerValue] == axis) {
GB_set_key_state(_gb, GB_KEY_LEFT, value < -0x4000);
GB_set_key_state(_gb, GB_KEY_RIGHT, value > 0x4000);
}
else if (y_axis && [y_axis integerValue] == axis) {
GB_set_key_state(_gb, GB_KEY_UP, value < -0x4000);
GB_set_key_state(_gb, GB_KEY_DOWN, value > 0x4000);
else if (axis == [y_axis integerValue]) {
if (value > JOYSTICK_HIGH) {
axisActive[1] = true;
GB_set_key_state(_gb, GB_KEY_DOWN, true);
GB_set_key_state(_gb, GB_KEY_UP, false);
}
else if (value < -JOYSTICK_HIGH) {
axisActive[1] = true;
GB_set_key_state(_gb, GB_KEY_DOWN, false);
GB_set_key_state(_gb, GB_KEY_UP, true);
}
else if (axisActive[1] && value < JOYSTICK_LOW && value > -JOYSTICK_LOW) {
axisActive[1] = false;
GB_set_key_state(_gb, GB_KEY_DOWN, false);
GB_set_key_state(_gb, GB_KEY_UP, false);
}
}
}

View File

@ -801,44 +801,36 @@ void run_gui(bool is_running)
case SDL_JOYAXISMOTION: {
static bool axis_active[2] = {false, false};
joypad_axis_t axis = get_joypad_axis(event.jaxis.axis);
if (axis == JOYPAD_AXISES_Y) {
if (event.jaxis.value > 0x4000) {
if (!axis_active[1]) {
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_DOWN;
}
axis_active[1] = true;
if (axis == JOYPAD_AXISES_X) {
if (!axis_active[0] && event.jaxis.value > JOYSTICK_HIGH) {
axis_active[0] = true;
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_RIGHT;
}
else if (event.jaxis.value < -0x4000) {
if (!axis_active[0]) {
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_UP;
}
axis_active[1] = true;
else if (!axis_active[0] && event.jaxis.value < -JOYSTICK_HIGH) {
axis_active[0] = true;
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_LEFT;
}
else {
axis_active[1] = false;
else if (axis_active[0] && event.jaxis.value < JOYSTICK_LOW && event.jaxis.value > -JOYSTICK_LOW) {
axis_active[0] = false;
}
}
else if (axis == JOYPAD_AXISES_X) {
if (event.jaxis.value > 0x4000) {
if (!axis_active[0]) {
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_RIGHT;
}
axis_active[0] = true;
else if (axis == JOYPAD_AXISES_Y) {
if (!axis_active[1] && event.jaxis.value > JOYSTICK_HIGH) {
axis_active[1] = true;
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_DOWN;
}
else if (event.jaxis.value < -0x4000) {
if (!axis_active[0]) {
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_LEFT;
}
axis_active[0] = true;
else if (!axis_active[1] && event.jaxis.value < -JOYSTICK_HIGH) {
axis_active[1] = true;
event.type = SDL_KEYDOWN;
event.key.keysym.scancode = SDL_SCANCODE_UP;
}
else {
axis_active[0] = false;
else if (axis_active[1] && event.jaxis.value < JOYSTICK_LOW && event.jaxis.value > -JOYSTICK_LOW) {
axis_active[1] = false;
}
}
}

View File

@ -6,6 +6,9 @@
#include <stdbool.h>
#include "shader.h"
#define JOYSTICK_HIGH 0x4000
#define JOYSTICK_LOW 0x3800
extern GB_gameboy_t gb;
extern SDL_Window *window;

View File

@ -8,6 +8,7 @@
#include "gui.h"
#include "shader.h"
#ifndef _WIN32
#define AUDIO_FREQUENCY 96000
#else
@ -161,14 +162,41 @@ static void handle_events(GB_gameboy_t *gb)
break;
case SDL_JOYAXISMOTION: {
static bool axis_active[2] = {false, false};
joypad_axis_t axis = get_joypad_axis(event.jaxis.axis);
if (axis == JOYPAD_AXISES_Y) {
GB_set_key_state(gb, GB_KEY_DOWN, event.jaxis.value > 0x4000);
GB_set_key_state(gb, GB_KEY_UP, event.jaxis.value < -0x4000);
if (axis == JOYPAD_AXISES_X) {
if (event.jaxis.value > JOYSTICK_HIGH) {
axis_active[0] = true;
GB_set_key_state(gb, GB_KEY_RIGHT, true);
GB_set_key_state(gb, GB_KEY_LEFT, false);
}
else if (event.jaxis.value < -JOYSTICK_HIGH) {
axis_active[0] = true;
GB_set_key_state(gb, GB_KEY_RIGHT, false);
GB_set_key_state(gb, GB_KEY_LEFT, true);
}
else if (axis_active[0] && event.jaxis.value < JOYSTICK_LOW && event.jaxis.value > -JOYSTICK_LOW) {
axis_active[0] = false;
GB_set_key_state(gb, GB_KEY_RIGHT, false);
GB_set_key_state(gb, GB_KEY_LEFT, false);
}
}
else if (axis == JOYPAD_AXISES_X) {
GB_set_key_state(gb, GB_KEY_RIGHT, event.jaxis.value > 0x4000);
GB_set_key_state(gb, GB_KEY_LEFT, event.jaxis.value < -0x4000);
else if (axis == JOYPAD_AXISES_Y) {
if (event.jaxis.value > JOYSTICK_HIGH) {
axis_active[1] = true;
GB_set_key_state(gb, GB_KEY_DOWN, true);
GB_set_key_state(gb, GB_KEY_UP, false);
}
else if (event.jaxis.value < -JOYSTICK_HIGH) {
axis_active[1] = true;
GB_set_key_state(gb, GB_KEY_DOWN, false);
GB_set_key_state(gb, GB_KEY_UP, true);
}
else if (axis_active[1] && event.jaxis.value < JOYSTICK_LOW && event.jaxis.value > -JOYSTICK_LOW) {
axis_active[1] = false;
GB_set_key_state(gb, GB_KEY_DOWN, false);
GB_set_key_state(gb, GB_KEY_UP, false);
}
}
}
break;