Skip to content

Commit

Permalink
Implement : Joystick support in the custom mode (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
CSaratakij committed Jan 7, 2021
1 parent 3f7411c commit 111bebd
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 7 deletions.
Binary file added font/RobotoMono-Bold.ttf
Binary file not shown.
10 changes: 9 additions & 1 deletion include/header.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once
#define BONGO_KEYPRESS_THRESHOLD 0
#define WINDOW_WIDTH 612
#define WINDOW_HEIGHT 352
#define MAX_FRAMERATE 60

#include <iostream>
#include <fstream>
Expand Down Expand Up @@ -29,14 +32,19 @@ sf::Texture &load_texture(std::string path);
}; // namespace data

namespace input {
void init();
bool init();

bool is_pressed(int key_code);

bool is_joystick_connected();
bool is_joystick_pressed(int key_code);

std::pair<double, double> bezier(double ratio, std::vector<double> &points, int length);

std::pair<double, double> get_xy();

void drawDebugPanel();

void cleanup();
}; // namespace input

Expand Down
19 changes: 18 additions & 1 deletion src/custom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace custom {
struct key {
Json::Value key_value;
Json::Value joy_value;
sf::Sprite sprite;
bool status;
double timer;
Expand All @@ -22,6 +23,13 @@ struct key {
data::error_msg("Custom image path is not set correctly", "Error reading configs");
throw;
}
if (_key_value.isMember("joyCodes")) {
if (!_key_value["joyCodes"].isArray()) {
data::error_msg("Custom joyCodes values is not set correctly", "Error reading configs");
throw;
}
joy_value = _key_value["joyCodes"];
}
status = false;
timer = -1;
}
Expand All @@ -32,6 +40,15 @@ struct key {
return true;
}
}

if (input::is_joystick_connected()) {
for (Json::Value &v : joy_value) {
if (input::is_joystick_pressed(v.asInt())) {
return true;
}
}
}

return false;
}

Expand Down Expand Up @@ -316,4 +333,4 @@ void draw() {
window.draw(mouse);
}
}
}; // namespace taiko
}; // namespace custom
222 changes: 221 additions & 1 deletion src/input.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "header.hpp"
#include <sstream>
#include <cmath>
#include <iomanip>
#include <SFML/Window.hpp>

#if defined(__unix__) || defined(__unix)
Expand All @@ -14,12 +17,43 @@ extern "C" {
#endif

#define TOTAl_INPUT_TABLE_SIZE 256
#define JOYSTICK_AXIS_DEADZONE 10.0f
#define JOYSTICK_TRIGGER_DEADZONE 3.0f

namespace input {
int horizontal, vertical;
int osu_x, osu_y, osu_h, osu_v;
bool is_letterbox, is_left_handed;

int last_joystick_keycode = -1;

std::string debugMessage;
std::string debugBitMessage;

sf::RectangleShape debugBackground;
sf::Font debugFont;
sf::Text debugText;


enum JoystickInputMapRange {
MinButton = 0,
MaxButton = 31,
LS_Left,
LS_Right,
LS_Up,
LS_Down,
RS_Left,
RS_Right,
RS_Up,
RS_Down,
DPad_Left,
DPad_Right,
DPad_Up,
DPad_Down,
LTrigger,
RTrigger
};

#if defined(__unix__) || defined(__unix)
xdo_t* xdo;
Display* dpy;
Expand All @@ -32,7 +66,7 @@ static int _XlibErrorHandler(Display *display, XErrorEvent *event) {

int INPUT_KEY_TABLE[TOTAl_INPUT_TABLE_SIZE];

void init() {
bool init() {
for (int i = 0; i < TOTAl_INPUT_TABLE_SIZE; i++) {
if (i >= 48 && i <= 57) { // number
INPUT_KEY_TABLE[i] = i - 48 + (int)sf::Keyboard::Key::Num0;
Expand Down Expand Up @@ -124,6 +158,24 @@ void init() {
horizontal = desktop.right;
vertical = desktop.bottom;
#endif

// loading font
if (!debugFont.loadFromFile("font/RobotoMono-Bold.ttf")) {
data::error_msg("Cannot find the font : RobotoMono-Bold.ttf", "Error loading font");
return false;
}

// initialize debug resource
debugBackground.setSize(sf::Vector2f(WINDOW_WIDTH, WINDOW_HEIGHT));
debugBackground.setFillColor(sf::Color(0, 0, 0, 128));

debugText.setFont(debugFont);
debugText.setCharacterSize(14);
debugText.setFillColor(sf::Color::White);
debugText.setPosition(10.0f, 4.0f);
debugText.setString(debugMessage);

return true;
}

sf::Keyboard::Key ascii_to_key(int key_code) {
Expand Down Expand Up @@ -169,6 +221,102 @@ bool is_pressed(int key_code) {
}
}

bool is_joystick_connected() {
return sf::Joystick::isConnected(0);
}

bool is_joystick_pressed(int key_code) {
int id = 0;
last_joystick_keycode = key_code;

// joystick button, range 0 - 31
if (key_code >= MinButton && key_code <= MaxButton) {
return sf::Joystick::isButtonPressed(id, key_code);
}
// joystick axis, range 32 - 45
else {
float axis = 0.0f;

switch (key_code) {
case LS_Left:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::X);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case LS_Right:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::X);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case LS_Up:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::Y);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case LS_Down:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::Y);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case RS_Left:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::U);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case RS_Right:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::U);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case RS_Up:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::V);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case RS_Down:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::V);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case DPad_Left:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::PovX);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case DPad_Right:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::PovX);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case DPad_Up:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::PovY);
return axis <= -JOYSTICK_AXIS_DEADZONE;
break;

case DPad_Down:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::PovY);
return axis >= JOYSTICK_AXIS_DEADZONE;
break;

case LTrigger:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::Z);
return axis >= JOYSTICK_TRIGGER_DEADZONE;
break;

case RTrigger:
axis = sf::Joystick::getAxisPosition(id, sf::Joystick::R);
return axis >= JOYSTICK_TRIGGER_DEADZONE;
break;

default:
return false;
break;
}
}

return false;
}

// bezier curve for osu and custom
std::pair<double, double> bezier(double ratio, std::vector<double> &points, int length) {
double fact[22] = {0.001, 0.001, 0.002, 0.006, 0.024, 0.12, 0.72, 5.04, 40.32, 362.88, 3628.8, 39916.8, 479001.6, 6227020.8, 87178291.2, 1307674368.0, 20922789888.0, 355687428096.0, 6402373705728.0, 121645100408832.0, 2432902008176640.0, 51090942171709440.0};
Expand Down Expand Up @@ -361,11 +509,83 @@ std::pair<double, double> get_xy() {
return std::make_pair(x, y);
}

void drawDebugPanel() {
if (!is_joystick_connected()) {
debugText.setString("No joystick found...");
window.draw(debugBackground);
window.draw(debugText);
return;
}

int joy_id = 0;

std::stringstream result;
sf::Joystick::Identification info = sf::Joystick::getIdentification(joy_id);

result << "Joystick connected : " << info.name.toAnsiString() << std::endl;
result << "Support button : " << sf::Joystick::getButtonCount(joy_id) << std::endl;

int offset = 0;
int counter = 0;
int max_button = (int)sf::Joystick::ButtonCount;
int max_row = 11;

for (int i = 0; i < max_button; ++i) {
int buttonID = (counter + offset);

bool isPressed = sf::Joystick::isButtonPressed(joy_id, buttonID);
std::string state = isPressed ? "PRESS" : "release";

result << std::setw(10) << "Button#" << std::setw(2) << buttonID << std::setw(1) << ": " << std::setw(5) << state;

counter += max_row;
bool shouldPrintNextLine = ((i + 1) % 3) == 0;

if (shouldPrintNextLine) {
result << std::endl;
counter = 0;
offset += 1;
}
}

result << std::endl;
result << "Axis : " << std::endl;

sf::Vector2f leftstick_axis;
sf::Vector2f rightstick_axis;
sf::Vector2f dpad_axis;
float left_trigger_axis;
float right_trigger_axis;

leftstick_axis.x = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::X);
leftstick_axis.y = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::Y);
rightstick_axis.x = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::U);
rightstick_axis.y = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::V);

dpad_axis.x = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::PovX);
dpad_axis.y = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::PovY);

left_trigger_axis = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::Z);
right_trigger_axis = sf::Joystick::getAxisPosition(joy_id, sf::Joystick::R);

result << "LStick : " << "( " << leftstick_axis.x << "," << leftstick_axis.y << " )" << std::endl;
result << "RStick : " << "( " << rightstick_axis.x << "," << rightstick_axis.y << " )" << std::endl;
result << "LTrigger : " << left_trigger_axis << std::endl;
result << "RTrigger : " << right_trigger_axis << std::endl;
result << "DPad : " << "( " << dpad_axis.x << "," << dpad_axis.y << " )" << std::endl;

debugText.setString(result.str());

window.draw(debugBackground);
window.draw(debugText);
}

void cleanup() {
#if defined(__unix__) || defined(__unix)
delete xdo;
XCloseDisplay(dpy);
#endif
}

};

Loading

1 comment on commit 111bebd

@Herobrineluis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me encanto

Please sign in to comment.