Skip to content

Commit

Permalink
Merge pull request #153 from Electronicks/master
Browse files Browse the repository at this point in the history
JoyShockMapper 3
  • Loading branch information
JibbSmart authored Mar 29, 2021
2 parents 289ce40 + c3d242b commit d69549a
Show file tree
Hide file tree
Showing 26 changed files with 1,007 additions and 672 deletions.
22 changes: 16 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,34 @@ Most recent updates will appear first.
This is a summary of new features and bugfixes. Read the README to learn how to use the features mentioned here.

## 3.0.0
Jibb added JSL-specific features to SDL2 so that JSM could use SDL2 instead. This means support for many non-gyro controllers, including Xbox, Stadia, and almost every common generic PC controller. Also made it so that low report-rate controllers (eg Switch controllers) are sampled multiple times for smooth gyro on high refresh rate monitors.
**SDL2 is now the official version of JSM going forward.** JSM will also be released with JSL for the time being in case there are features there unavailable in SDL2 yet.
Nicolas added ViGEm support for virtual xbox and DS4 for buttons, triggers and sticks as well as rumble forwarding.
Added colored console lines
Added DS4 rumble commands and light bar setting
Added rumble commands and DS4 light bar setting and TOUCH binding
Added DS4 dual stage mode for toupad touch and click.
Added hair trigger soft press as a negative threshold and trigger modes SCROLL_WHEEL and NO_SKIP_EXCLUSIVE
Added ability to hide JSM from the taskbar when minimized, with a checkbox in the tray icon
Added help strings for button mapping
Added argument to RECONNECT_CONTROLLERS [MERGE|SPLIT] used to determine joycon behaviour
Added handler to modeshift a gyro button to NONE\ as no button since NONE is used to remove the modeshift.
Handle drag n drop files into the console better
Improve command error handling
Improved README separation
Improved desktop recommended config

Jibb added JSL-specific features to SDL2 so that JSM could use SDL2 instead. This means support for many non-gyro controllers, including Xbox, Stadia, and almost every common generic PC controller. Also made it so that low report-rate controllers (eg Switch controllers) are sampled multiple times for smooth gyro on high refresh rate monitors.

### Features
* New Bindings: TOUCH, T1-T25 touch buttons, Touch stick bindings
* New settings for touch joystick such as mode, inner deadzone, and stick radius
* New Bindings: TOUCH for the touch pad and dual stage mode for TOUCH and CAPTURE bindings
* New Mappings for ViGEm controller bindings. See README
* Added Mappings SMALL_RUMBLE, BIG_RUMBLE and Rhhhh (h being hex digits)
* Added settings STICK_DEADZONE_INNER|OUTER, TICK_TIME (aka polling period), LIGHT_BAR, SCROLL_SENS, VIRTUAL_CONTROLLER, RUMBLE ( = ON|OFF) and TOUCHPAD_DUAL_STAGE_MODE
* Added JOYCON_SIDEWAYS as a controller orientation
* Added Stick Mode SCROLL_WHEEL
* Added TriggerMode NO_SKIP_EXCLUSIVE
* Assigning a negative value to trigger threshold enables hair trigger
* New setting HIDE\_MINIMIZED will hide JSM when set to ON. OFF is default
* Support for many non-gyro controllers: Xbox, Stadia, GameCube, PS3 (without motion), and many generic PC controllers.
* Added TICK\_TIME to set how many milliseconds between reading controllers (default of 3 means about 333Hz).
* Support for many non-gyro controllers: Xbox, Stadia, GameCube, PS3 (without motion), and many generic PC controllers via SDL2

## 2.2.0
Nicolas added more keybinds. Robin fixed issues with building on Linux and improved PlayStation controller support.
Expand Down
4 changes: 2 additions & 2 deletions JoyShockMapper/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
Expand Down Expand Up @@ -125,7 +125,7 @@ SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
Standard: Cpp17
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
Expand Down
44 changes: 24 additions & 20 deletions JoyShockMapper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_executable (
include/JoyShockMapper.h
include/ColorCodes.h
include/GamepadMotion.hpp
include/Gamepad.h
)

if (WINDOWS)
Expand All @@ -39,23 +40,16 @@ if (WINDOWS)
src/win32/PlatformDefinitions.cpp
src/win32/WindowsTrayIcon.cpp include/win32/WindowsTrayIcon.h
src/win32/Whitelister.cpp
src/win32/Gamepad.cpp include/win32/Gamepad.h
src/win32/Gamepad.cpp
"Win32 Dialog.rc" include/win32/resource.h
)

if(SDL)
target_sources (
${BINARY_NAME} PRIVATE
src/JoyShockLibrary.cpp include/JoyShockLibrary.h
src/SDL2Wrapper.cpp include/JoyShockLibrary.h
)
endif()

set_target_properties (
${BINARY_NAME} PROPERTIES
WIN32_EXECUTABLE ON
VS_STARTUP_PROJECT "${BINARY_NAME}"
VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)/$(Configuration)/"
)

# ViGEmClient
CPMAddPackage (
Expand All @@ -65,26 +59,22 @@ if (WINDOWS)
)

include_external_msproject(ViGEmClient
"_deps/vigemclient-src/src/ViGEmClient.vcxproj")

SET(ViGEmClient_GUID_CMAKE "7DB06674-1F4F-464B-8E1C-172E9587F9DC" CACHE INTERNAL "Project GUID")

"${PROJECT_BINARY_DIR}/_deps/vigemclient-src/src/ViGEmClient.vcxproj")

set_target_properties(ViGEmClient PROPERTIES
MAP_IMPORTED_CONFIG_DEBUG DEBUG_LIB
MAP_IMPORTED_CONFIG_RELEASE RELEASE_LIB
)

set_target_properties(ViGEmClient PROPERTIES
VS_PLATFORM_TOOLSET "v141"
IMPORTED_LOCATION "${PROJECT_BINARY_DIR}/lib/debug/$(PlatformShortName)/ViGEmClient.lib"
IMPORTED_LOCATION "${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}/$(PlatformShortName)/ViGEmClient.lib"
INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_BINARY_DIR}/_deps/vigemclient-src/include"
)

add_dependencies(${BINARY_NAME} ViGEmClient)

set_target_properties (
${BINARY_NAME} PROPERTIES
LINK_LIBRARIES "${PROJECT_BINARY_DIR}/lib/debug/$(PlatformShortName)/ViGEmClient.lib"
target_link_libraries (
${BINARY_NAME} PRIVATE
debug "${PROJECT_BINARY_DIR}/lib/debug/$(PlatformShortName)/ViGEmClient.lib"
optimized "${PROJECT_BINARY_DIR}/lib/release/$(PlatformShortName)/ViGEmClient.lib"
)

target_include_directories (
Expand All @@ -109,6 +99,14 @@ if (WINDOWS)
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/$<TARGET_FILE_NAME:JoyShockLibrary>"
)
endif()

set_target_properties (
${BINARY_NAME} PROPERTIES
WIN32_EXECUTABLE ON
VS_STARTUP_PROJECT "${BINARY_NAME}"
VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)/$(Configuration)/"
VS_DEBUGGER_COMMAND_ARGUMENTS "$(SolutionDir)..\\$(ProjectName)\\dist"
)

add_definitions(/bigobj)
endif ()
Expand All @@ -121,6 +119,7 @@ if (LINUX)
src/linux/PlatformDefinitions.cpp
src/linux/StatusNotifierItem.cpp include/linux/StatusNotifierItem.h
src/linux/Whitelister.cpp
src/linux/Gamepad.cpp
)
endif ()

Expand All @@ -145,6 +144,9 @@ if(SDL)
# 2.0.15 hasn't released yet, so let's use a specific commit
GIT_TAG c287087fcce57af086c0a52f74fcdb74e9084c55
)

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

target_link_libraries (
${BINARY_NAME} PRIVATE
Platform::Dependencies
Expand All @@ -153,6 +155,7 @@ if(SDL)

install (
TARGETS ${BINARY_NAME} SDL2
RUNTIME DESTINATION ${PACKAGE_DIR}
)
else()
# JoyShockLibrary
Expand All @@ -170,6 +173,7 @@ else()

install (
TARGETS ${BINARY_NAME} JoyShockLibrary
RUNTIME DESTINATION ${PACKAGE_DIR}
)
endif()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ typedef struct _XUSB_REPORT XUSB_REPORT;
typedef struct _DS4_REPORT DS4_REPORT;
typedef enum _VIGEM_ERRORS VIGEM_ERRORS;

#if defined(WIN32)
#define VIGEM_CALLBACK _stdcall
#else
#define VIGEM_CALLBACK
#endif

union Indicator
{
uint8_t led;
Expand Down Expand Up @@ -40,15 +46,15 @@ class Gamepad
ControllerScheme getType() const;

private:
static void x360Notification(
static void VIGEM_CALLBACK x360Notification(
PVIGEM_CLIENT client,
PVIGEM_TARGET target,
uint8_t largeMotor,
uint8_t smallMotor,
uint8_t ledNumber,
void *userData);

static void ds4Notification(
static void VIGEM_CALLBACK ds4Notification(
PVIGEM_CLIENT client,
PVIGEM_TARGET target,
uint8_t largeMotor,
Expand Down
73 changes: 45 additions & 28 deletions JoyShockMapper/include/JSMAssignment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,45 +29,53 @@ class JSMAssignment : public JSMCommand
{
smatch results;
_ASSERT_EXPR(_parse, L"There is no function defined to parse this command.");
if (arguments.compare(0, 4, "HELP") == 0 && !_help.empty())
if (arguments.empty())
{
DisplayCurrentValue();
}
else if (arguments.compare(0, 4, "HELP") == 0 && !_help.empty())
{
// Show help.
COUT << _help << endl;
}
else if (arguments.empty() || regex_match(arguments, results, regex(R"(\s*=\s*(.*))")))
else if (regex_match(arguments, results, regex(R"(\s*=\s*(.*))")))
{
string fwd_args(results.empty() ? arguments : results[1].str());
if (fwd_args.rfind("DEFAULT", 0) == 0)
string assignment(results.empty() ? arguments : results[1].str());
if (assignment.rfind("DEFAULT", 0) == 0)
{
_var.Reset();
}
else if (!_parse(this, fwd_args) && !_help.empty())
else if (!_parse(this, assignment))
{
COUT << _help << endl
<< "The "; // Parsing has failed. Show help.
CERR << "Error assigning ";
COUT_INFO << assignment;
CERR << " to " << _displayName << endl;
CERR << "See ";
COUT_INFO << "HELP";
CERR << " and ";
COUT_INFO << "README";
COUT << " command can lead you to further details on this command." << endl;
CERR << " commands for further details." << endl;
}
}
else if (!_help.empty())
{
COUT << _help << endl
<< "The "; // Parsing has failed. Show help.
// Parsing has failed.
CERR << "Error when processing the assignment. See the ";
COUT_INFO << "README";
COUT << " command can lead you to further details on this command." << endl;
CERR << " for details on valid assignment values" << endl;
}
return true; // Command is completely processed
}

static bool ModeshiftParser(ButtonID modeshift, JSMSetting<T>* setting, JSMCommand::ParseDelegate parser, JSMCommand* cmd, in_string argument)
static bool ModeshiftParser(ButtonID modeshift, JSMSetting<T>* setting, JSMCommand::ParseDelegate* parser, JSMCommand* cmd, in_string argument)
{
if (setting && argument.compare("NONE") == 0)
{
setting->MarkModeshiftForRemoval(modeshift);
COUT << "Modeshift " << modeshift << "," << setting->_id << " has been removed." << endl;
COUT << "Modeshift " << modeshift << "," << cmd->_name << " has been removed." << endl;
return true;
}
return parser(cmd, argument);
return (*parser)(cmd, argument);
}

// The default parser uses the overloaded >> operator to parse
Expand All @@ -76,17 +84,10 @@ class JSMAssignment : public JSMCommand
static bool DefaultParser(JSMCommand* cmd, in_string data)
{
auto inst = dynamic_cast<JSMAssignment<T>*>(cmd);
if (data.empty())
{
//No assignment? Display current assignment
COUT << inst->_displayName << " = " << inst->_var.get() << endl;
return true;
}

stringstream ss(data);
// Read the value
T value = T();
ss >> value;
T value(inst->ReadValue(ss));
if (!ss.fail())
{
T oldVal = inst->_var;
Expand All @@ -108,12 +109,25 @@ class JSMAssignment : public JSMCommand
return false;
}

void DisplayNewValue(T newValue)
virtual void DisplayNewValue(T newValue)
{
// See Specialization for T=Mapping at the end of this file
COUT << _displayName << " has been set to " << newValue << endl;
}

virtual void DisplayCurrentValue()
{
COUT << _displayName << " = " << _var.get() << endl;
}

virtual T ReadValue(stringstream& in)
{
// Default value reader
T value = T();
in >> value;
return value;
}

virtual unique_ptr<JSMCommand> GetModifiedCmd(char op, in_string chord) override
{
stringstream ss(chord);
Expand All @@ -129,7 +143,7 @@ class JSMAssignment : public JSMCommand
//Create Modeshift
string name = chord + op + _displayName;
unique_ptr<JSMCommand> chordAssignment(new JSMAssignment<T>(name, *settingVar->AtChord(btn)));
chordAssignment->SetHelp(_help)->SetParser(bind(&JSMAssignment<T>::ModeshiftParser, btn, settingVar, _parse, placeholders::_1, placeholders::_2))->SetTaskOnDestruction(bind(&JSMSetting<T>::ProcessModeshiftRemoval, settingVar, btn));
chordAssignment->SetHelp(_help)->SetParser(bind(&JSMAssignment<T>::ModeshiftParser, btn, settingVar, &_parse, placeholders::_1, placeholders::_2))->SetTaskOnDestruction(bind(&JSMSetting<T>::ProcessModeshiftRemoval, settingVar, btn));
return chordAssignment;
}
auto buttonVar = dynamic_cast<JSMButton*>(&_var);
Expand Down Expand Up @@ -164,20 +178,18 @@ class JSMAssignment : public JSMCommand
}

unsigned int _listenerId;
bool _hasListener;

public:
JSMAssignment(in_string name, in_string displayName, JSMVariable<T>& var, bool inNoListener = false)
: JSMCommand(name)
, _var(var)
, _displayName(displayName)
, _listenerId(0)
, _hasListener(!inNoListener)
{
// Child Classes assign their own parser. Use bind to convert instance function call
// into a static function call.
SetParser(&JSMAssignment::DefaultParser);
if (_hasListener)
if (!inNoListener)
{
_listenerId = _var.AddOnChangeListener(bind(&JSMAssignment::DisplayNewValue, this, placeholders::_1));
}
Expand All @@ -193,9 +205,14 @@ class JSMAssignment : public JSMCommand
{
}

JSMAssignment(JSMButton& var)
: JSMAssignment(magic_enum::enum_name(var._id).data(), var)
{
}

virtual ~JSMAssignment()
{
if (_hasListener)
if (_listenerId != 0)
{
_var.RemoveOnChangeListener(_listenerId);
}
Expand Down
2 changes: 1 addition & 1 deletion JoyShockMapper/include/JSMVariable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class JSMVariable
// Default value of the variable. Cannot be changed after construction.
const T _defVal;

JSMVariable(T defaultValue = T(0))
JSMVariable(T defaultValue = T())
: _value(defaultValue)
, _onChangeListeners()
, _filter(&NoFiltering) // _filter is always valid
Expand Down
Loading

0 comments on commit d69549a

Please sign in to comment.