Commit efff26a5 authored by reassembler's avatar reassembler
Browse files

Analog: Dead Zone, Support In Menus, Split Axis, Toggle Digital Controls.

parent 56b4f410
......@@ -116,22 +116,44 @@
<coin>4</coin>
<menu>5</menu>
</padconfig>
<!-- Digital Controls: Steering Adjust Speed (1 to 9) -->
<steerspeed>3</steerspeed>
<!-- Analog Controls -->
<!-- Digital Controls: Pedal Adjust Speed (1 to 9) -->
<pedalspeed>4</pedalspeed>
<!-- Analog Controls
0 = Off
1 = On
2 = Wheel Only
-->
<analog enabled = "0">
<!-- Select axis for analog controls -->
<!-- Select axis for analog controls
You can place the accelerator and the brake on the same axis if your controller
has a split axis setup. This is best avoided though.
-->
<axis>
<wheel>0</wheel>
<accel>2</accel>
<brake>3</brake>
</axis>
<!-- Amount of wheel turning circle to use.
Example: 0 means use the entire wheel
larger values mean to progressively use less of the wheel turning circle -->
<wheelzone>75</wheelzone>
<!-- Analog Wheel Settings -->
<wheel>
<!-- Amount of wheel turning circle to use.
Example: 0 means use the entire wheel (this works best if haptic is enabled)
larger values mean to progressively use less of the wheel turning circle -->
<zone>50</zone>
<!-- Dead Zone In Centre Of Wheel. Total Wheel Range = 128
A Dead zone is useful if the centre accuracy of your wheel is poor.
A good Logitech Racing wheel should not need this -->
<dead>0</dead>
</wheel>
<!-- Force Feedback / Haptic Support -->
<haptic enabled = "1">
<haptic enabled = "0">
<!-- Make both of the below values negative,
if force feedback is in the wrong direction -->
......@@ -142,17 +164,11 @@
<!-- Minimum Force To Apply (0 to max_force) -->
<min_force>7000</min_force>
<!-- Length of each effect. (1/x seconds) -->
<!-- Length of each effect. (1/x seconds) 1/20th suggested. -->
<force_duration>20</force_duration>
</haptic>
</analog>
<!-- Digital Controls: Steering Adjust Speed (1 to 9) -->
<steerspeed>3</steerspeed>
<!-- Digital Controls: Pedal Adjust Speed (1 to 9) -->
<pedalspeed>4</pedalspeed>
</controls>
<!--
......
......@@ -44,8 +44,18 @@ void OInputs::init()
void OInputs::analog()
{
input_steering = input.a_wheel;
input_acc = input.a_accel;
input_brake = input.a_brake;
// Analog Pedals
if (input.analog == 1)
{
input_acc = input.a_accel;
input_brake = input.a_brake;
}
// Digital Pedals
else
{
digital_pedals();
}
}
// Digital Simulation
......@@ -87,6 +97,11 @@ void OInputs::simulate_analog()
}
}
digital_pedals();
}
void OInputs::digital_pedals()
{
// ------------------------------------------------------------------------
// ACCELERATION
// ------------------------------------------------------------------------
......
......@@ -79,6 +79,8 @@ private:
// Brake Input
int16_t input_brake;
void digital_pedals();
};
extern OInputs oinputs;
\ No newline at end of file
......@@ -119,8 +119,9 @@ void Config::load(const std::string &filename)
controls.axis[0] = pt_config.get("controls.analog.axis.wheel", 0);
controls.axis[1] = pt_config.get("controls.analog.axis.accel", 2);
controls.axis[2] = pt_config.get("controls.analog.axis.brake", 3);
controls.analog_zone = pt_config.get("controls.analog.wheelzone", 75);
controls.wheel[0] = pt_config.get("controls.analog.wheel.zone", 75);
controls.wheel[1] = pt_config.get("controls.analog.wheel.dead", 0);
controls.haptic = pt_config.get("controls.analog.haptic.<xmlattr>.enabled", 0);
controls.max_force = pt_config.get("controls.analog.haptic.max_force", 9000);
controls.min_force = pt_config.get("controls.analog.haptic.min_force", 8500);
......
......@@ -68,7 +68,7 @@ struct controls_settings_t
int keyconfig[10]; // Keyboard Button Config
int analog; // Use analog controls
int axis[3]; // Analog Axis
int analog_zone; // Percentage of wheel turning circle to use
int wheel[2]; // Wheel Settings
int haptic; // Force Feedback Enabled
int max_force;
......
......@@ -373,21 +373,21 @@ void Menu::draw_text(std::string s)
void Menu::tick_menu()
{
// Tick Controls
if (input.has_pressed(Input::DOWN))
if (input.has_pressed(Input::DOWN) || input.is_analog_r())
{
osoundint.queue_sound(sound::BEEP1);
if (++cursor >= (int16_t) menu_selected->size())
cursor = 0;
}
else if (input.has_pressed(Input::UP))
else if (input.has_pressed(Input::UP) || input.is_analog_l())
{
osoundint.queue_sound(sound::BEEP1);
if (--cursor < 0)
cursor = menu_selected->size() - 1;
}
else if (input.has_pressed(Input::ACCEL) || input.has_pressed(Input::START))
else if (input.has_pressed(Input::ACCEL) || input.has_pressed(Input::START) || input.is_analog_select())
{
// Get option that was selected
const char* OPTION = menu_selected->at(cursor).c_str();
......@@ -549,8 +549,9 @@ void Menu::tick_menu()
}
else if (SELECTED(ENTRY_ANALOG))
{
config.controls.analog = !config.controls.analog;
input.analog = config.controls.analog != 0;
if (++config.controls.analog == 3)
config.controls.analog = 0;
input.analog = config.controls.analog;
}
else if (SELECTED(ENTRY_REDEFKEY))
{
......@@ -561,7 +562,7 @@ void Menu::tick_menu()
else if (SELECTED(ENTRY_REDEFJOY))
{
state = STATE_REDEFINE_JOY;
redef_state = config.controls.analog ? 2 : 0; // Ignore pedals when redefining analog
redef_state = config.controls.analog == 1 ? 2 : 0; // Ignore pedals when redefining analog
input.joy_button = -1;
}
else if (SELECTED(ENTRY_DSTEER))
......@@ -714,7 +715,12 @@ void Menu::refresh_menu()
set_menu_text(ENTRY_GEAR, s);
}
else if (SELECTED(ENTRY_ANALOG))
set_menu_text(ENTRY_ANALOG, config.controls.analog ? "ON" : "OFF");
{
if (config.controls.analog == 0) s = "OFF";
else if (config.controls.analog == 1) s = "ON";
else if (config.controls.analog == 2) s = "ON WHEEL ONLY";
set_menu_text(ENTRY_ANALOG, s);
}
else if (SELECTED(ENTRY_DSTEER))
set_menu_text(ENTRY_DSTEER, config.to_string(config.controls.steer_speed));
else if (SELECTED(ENTRY_DPEDAL))
......
......@@ -74,17 +74,17 @@ int TTrial::tick()
{
return BACK_TO_MENU;
}
else if (input.has_pressed(Input::LEFT))
else if (input.has_pressed(Input::LEFT) || input.is_analog_l())
{
if (--level_selected < 0)
level_selected = sizeof(FERRARI_POS) - 1;
}
else if (input.has_pressed(Input::RIGHT))
else if (input.has_pressed(Input::RIGHT)|| input.is_analog_r())
{
if (++level_selected > sizeof(FERRARI_POS) - 1)
level_selected = 0;
}
else if (input.has_pressed(Input::START) || input.has_pressed(Input::ACCEL))
else if (input.has_pressed(Input::START) || input.has_pressed(Input::ACCEL) || input.is_analog_select())
{
outils::convert_counter_to_time(best_times[level_selected], best_converted);
......
......@@ -228,8 +228,8 @@ int main(int argc, char* argv[])
state = config.menu.enabled ? STATE_INIT_MENU : STATE_INIT_GAME;
// Initalize controls
input.init(config.controls.keyconfig, config.controls.padconfig,
config.controls.analog != 0, config.controls.axis, config.controls.analog_zone);
input.init(config.controls.keyconfig, config.controls.padconfig,
config.controls.analog, config.controls.axis, config.controls.wheel);
if (config.controls.haptic)
config.controls.haptic = forcefeedback::init(config.controls.max_force, config.controls.min_force, config.controls.force_duration);
......
......@@ -8,6 +8,7 @@
See license.txt for more details.
***************************************************************************/
#include <cstdlib>
#include "sdl/input.hpp"
Input input;
......@@ -20,13 +21,14 @@ Input::~Input(void)
{
}
void Input::init(int* key_config, int* pad_config, bool analog, int* axis, int analog_zone)
void Input::init(int* key_config, int* pad_config, int analog, int* axis, int* wheel)
{
this->key_config = key_config;
this->pad_config = pad_config;
this->analog = analog;
this->axis = axis;
this->analog_zone = analog_zone;
this->wheel_zone = wheel[0];
this->wheel_dead = wheel[1];
gamepad = SDL_NumJoysticks() >= 1;
......@@ -34,6 +36,9 @@ void Input::init(int* key_config, int* pad_config, bool analog, int* axis, int a
{
stick = SDL_JoystickOpen(0);
}
a_wheel = CENTRE;
delay = 0;
}
void Input::close()
......@@ -125,6 +130,8 @@ void Input::handle_key(const int key, const bool is_pressed)
}
}
#include <iostream>
void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
{
int16_t value = evt->value;
......@@ -136,7 +143,7 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
if (evt->axis == 0)
{
// Neural
if ( (value > -3200 ) && (value < 3200 ) )
if ( (value > -DIGITAL_DEAD ) && (value < DIGITAL_DEAD ) )
{
keys[LEFT] = false;
keys[RIGHT] = false;
......@@ -154,7 +161,7 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
else if (evt->axis == 1)
{
// Neural
if ( (value > -3200 ) && (value < 3200 ) )
if ( (value > -DIGITAL_DEAD ) && (value < DIGITAL_DEAD ) )
{
keys[UP] = false;
keys[DOWN] = false;
......@@ -173,10 +180,10 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
else
{
// Steering
// OutRun requires values between 0x48 and 0xb8. 0x80 is center
// OutRun requires values between 0x48 and 0xb8.
if (evt->axis == axis[0])
{
int percentage_adjust = ((analog_zone) << 8) / 100;
int percentage_adjust = ((wheel_zone) << 8) / 100;
int adjusted = value + ((value * percentage_adjust) >> 8);
// Make 0 hard left, and 0x80 centre value.
......@@ -188,10 +195,42 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
else if (adjusted > 0xC0)
adjusted = 0xC0;
//std::cout << "wheel zone : " << analog_zone << " : " << std::hex << " : " << (int) adjusted << std::endl;
// Remove Dead Zone
if (wheel_dead)
{
if (std::abs(CENTRE - adjusted) <= wheel_dead)
adjusted = CENTRE;
}
//std::cout << "wheel zone : " << wheel_zone << " : " << std::hex << " : " << (int) adjusted << std::endl;
a_wheel = adjusted;
}
// Accelerator
// Accelerator and Brake [Combined Axis - Best Avoided!]
else if (axis[1] == axis[2])
{
// Accelerator
if (value < -DIGITAL_DEAD)
{
value = -value;
int adjusted = 0xBF - ((value + (1 << 15)) >> 9);
adjusted += (adjusted >> 2);
a_accel = adjusted;
}
// Brake
else if (value > DIGITAL_DEAD)
{
value = -value;
int adjusted = 0xBF - ((value + (1 << 15)) >> 9);
adjusted += (adjusted >> 2);
a_brake = adjusted;
}
else
{
a_accel = 0;
a_brake = 0;
}
}
// Accelerator [Single Axis]
else if (evt->axis == axis[1])
{
// Scale input to be in the range of 0 to 0x7F
......@@ -199,7 +238,7 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
adjusted += (adjusted >> 2);
a_accel = adjusted;
}
// Brake
// Brake [Single Axis]
else if (evt->axis == axis[2])
{
// Scale input to be in the range of 0 to 0x7F
......@@ -210,6 +249,47 @@ void Input::handle_joy_axis(SDL_JoyAxisEvent* evt)
}
}
// Use analog controls for menu.
bool Input::is_analog_l()
{
if (analog && a_wheel < CENTRE - 0x10)
{
if (--delay < 0)
{
delay = DELAY_RESET;
return true;
}
}
return false;
}
bool Input::is_analog_r()
{
if (analog && a_wheel > CENTRE + 0x10)
{
if (--delay < 0)
{
delay = DELAY_RESET;
return true;
}
}
return false;
}
bool Input::is_analog_select()
{
if (analog && a_accel > 0x50)
{
if (--delay < 0)
{
delay = DELAY_RESET;
return true;
}
}
return false;
}
void Input::handle_joy_down(SDL_JoyButtonEvent* evt)
{
// Latch joystick button presses for redefines
......
......@@ -41,7 +41,7 @@ public:
bool gamepad;
// Use analog controls
bool analog;
int analog;
// Latch last key press for redefines
int key_press;
......@@ -57,7 +57,7 @@ public:
Input(void);
~Input(void);
void init(int*, int*, const bool, int*, const int);
void init(int*, int*, const int, int*, int*);
void close();
void handle_key_up(SDL_keysym*);
......@@ -68,8 +68,16 @@ public:
void frame_done();
bool is_pressed(presses p);
bool has_pressed(presses p);
bool is_analog_l();
bool is_analog_r();
bool is_analog_select();
private:
static const int CENTRE = 0x80;
// Digital Dead Zone
static const int DIGITAL_DEAD = 3200;
// SDL Joystick / Keypad
SDL_Joystick *stick;
......@@ -78,7 +86,11 @@ private:
int* key_config;
int* axis;
int analog_zone;
int wheel_zone;
int wheel_dead;
static const int DELAY_RESET = 60;
int delay;
void handle_key(const int, const bool);
void handle_joy(const uint8_t, const bool);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment