├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── third-party ├── CMakeLists.txt ├── catch.cmake ├── vigemclient.cmake ├── favhidclient.cmake ├── cppwinrt.cmake └── vjoy.cmake ├── utilities ├── CMakeLists.txt ├── list-devices.cpp └── render.cpp ├── .gitignore ├── lib ├── AxisInformation.cpp ├── EventSink.cpp ├── Source.cpp ├── manifest.xml ├── EventSource.cpp ├── include │ └── cpp-remapper │ │ ├── OutputDevice.h │ │ ├── EventSink.h │ │ ├── EventSource.h │ │ ├── MappableOutput.h │ │ ├── Percent.h │ │ ├── ViGEmClient.h │ │ ├── InputDeviceCollection.h │ │ ├── Clock.h │ │ ├── ButtonToAxis.h │ │ ├── MomentaryToLatchedButton.h │ │ ├── ClosedPipeline.h │ │ ├── FAVHIDDevice.h │ │ ├── FunctionTransform.h │ │ ├── AxisInformation.h │ │ ├── ShortPressLongPress.h │ │ ├── easymode.h │ │ ├── AxisCurve.h │ │ ├── EventLoop.h │ │ ├── VJoyDevice.h │ │ ├── FunctionSink.h │ │ ├── MappableX360Output.h │ │ ├── LatchedToMomentaryButton.h │ │ ├── AnyOfButton.h │ │ ├── Sink.h │ │ ├── AxisToHat.h │ │ ├── CompositeSink.h │ │ ├── SourcePipeline.h │ │ ├── SinkPipeline.h │ │ ├── render_axis.h │ │ ├── MappableDS4Output.h │ │ ├── Shift.h │ │ ├── Controls.h │ │ ├── ViGEmTarget.h │ │ ├── function_traits.h │ │ ├── SquareDeadzone.h │ │ ├── AxisTrimmer.h │ │ ├── TransformPipeline.h │ │ ├── devicedb.h │ │ ├── Source.h │ │ ├── X360Device.h │ │ ├── AxisToButtons.h │ │ ├── maybe_shared_ptr.h │ │ ├── InputDevice.h │ │ ├── HidHide.h │ │ ├── SourcePtr.h │ │ ├── DS4Device.h │ │ ├── MappableVJoyOutput.h │ │ ├── MappableFAVHIDOutput.h │ │ ├── DeviceSpecifier.h │ │ ├── MappableInput.h │ │ ├── SinkPtr.h │ │ ├── HatToButtons.h │ │ ├── TransformPtr.h │ │ ├── connections.h │ │ └── Profile.h ├── MappableOutput.cpp ├── ButtonToAxis.cpp ├── Percent.cpp ├── AnyOfButton.cpp ├── MomentaryToLatchedButton.cpp ├── LatchedToMomentaryButton.cpp ├── AxisToButtons.cpp ├── Clock.cpp ├── AxisTrimmer.cpp ├── AxisToHat.cpp ├── connections.cpp ├── SquareDeadzone.cpp ├── AxisCurve.cpp ├── ShortPressLongPress.cpp ├── ViGEmClient.cpp ├── CMakeLists.txt ├── FAVHIDDevice.cpp ├── MappableX360Output.cpp ├── InputDeviceCollection.cpp ├── X360Device.cpp ├── MappableDS4Output.cpp ├── DeviceSpecifier.cpp ├── HatToButtons.cpp ├── Profile.cpp ├── DS4Device.cpp ├── render_axis.cpp ├── MappableVJoyOutput.cpp ├── EventLoop.cpp ├── VJoyDevice.cpp ├── MappableFAVHIDOutput.cpp └── MappableInput.cpp ├── tests ├── test.cpp ├── FunctionSink_test.cpp ├── FunctionTransform_test.cpp ├── CMakeLists.txt ├── tests.h ├── AnyOfButton_test.cpp ├── Shift_test.cpp ├── ButtonToAxis_test.cpp ├── MomentaryToLatchedButton_test.cpp ├── FakeClock.h ├── LatchedToMomentaryButton_test.cpp ├── FakeClock.cpp ├── ShortPressLongPress_test.cpp ├── AxisToHat_test.cpp ├── AxisCurve_test.cpp ├── CompositeSink_test.cpp ├── SquareDeadzone_test.cpp ├── AxisToButtons_test.cpp ├── Profile_test.cpp ├── AxisTrimmer_test.cpp ├── connections_test.cpp └── HatToButtons_test.cpp ├── legacy_profiles.cmake ├── LICENSE ├── example.cpp ├── .clang-format ├── CMakeLists.txt └── .vscode └── settings.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [fredemmott] 2 | -------------------------------------------------------------------------------- /third-party/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(catch.cmake) 2 | include(cppwinrt.cmake) 3 | include(favhidclient.cmake) 4 | include(vjoy.cmake) 5 | include(vigemclient.cmake) 6 | -------------------------------------------------------------------------------- /utilities/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_cppremapper_executable( 2 | list-devices 3 | list-devices.cpp 4 | ) 5 | add_cppremapper_executable( 6 | render 7 | render.cpp 8 | ) 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ilk 2 | *.pdb 3 | .vs/ 4 | *.exe 5 | *.obj 6 | *.lib 7 | 8 | /profiles/ 9 | vJoyInterface.dll 10 | /bin/ 11 | *~ 12 | *.bmp 13 | *.exp 14 | /build/ 15 | /out/ 16 | -------------------------------------------------------------------------------- /third-party/catch.cmake: -------------------------------------------------------------------------------- 1 | add_library( 2 | ThirdParty-Catch2 3 | INTERFACE 4 | ) 5 | 6 | target_include_directories( 7 | ThirdParty-Catch2 8 | INTERFACE 9 | "${CMAKE_CURRENT_SOURCE_DIR}/catch2" 10 | ) 11 | -------------------------------------------------------------------------------- /lib/AxisInformation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | // This file exists just to give clear compile errors 10 | #include 11 | -------------------------------------------------------------------------------- /third-party/vigemclient.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | 3 | FetchContent_Declare( 4 | FC_ViGEmClient 5 | URL "https://github.com/ViGEm/ViGEmClient/archive/refs/tags/v1.21.222.0.zip" 6 | URL_HASH "SHA256=4c61f0a82ea1153e271fe760712a97f4edaf64ad5f4244aca78eead74a3749b9" 7 | ) 8 | FetchContent_MakeAvailable(FC_ViGEmClient) 9 | 10 | add_library(ThirdParty-ViGEmClient ALIAS ViGEmClient) 11 | -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #define CATCH_CONFIG_MAIN 10 | 11 | // Don't intercept ASAN or standard library exceptions 12 | #define CATCH_CONFIG_NO_WINDOWS_SEH 13 | 14 | #include 15 | -------------------------------------------------------------------------------- /lib/EventSink.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #include 9 | 10 | namespace fredemmott::inputmapping { 11 | 12 | EventSink::~EventSink() { 13 | } 14 | 15 | }// namespace fredemmott::inputmapping 16 | -------------------------------------------------------------------------------- /lib/Source.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #include 10 | 11 | namespace fredemmott::inputmapping { 12 | 13 | AnySource::~AnySource() { 14 | } 15 | 16 | }// namespace fredemmott::inputmapping 17 | -------------------------------------------------------------------------------- /lib/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | UTF-8 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /lib/EventSource.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #include 9 | 10 | namespace fredemmott::inputmapping { 11 | 12 | EventSource::EventSource() { 13 | } 14 | 15 | EventSource::~EventSource() { 16 | } 17 | 18 | }// namespace fredemmott::inputmapping 19 | -------------------------------------------------------------------------------- /lib/include/cpp-remapper/OutputDevice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace fredemmott::inputmapping { 13 | 14 | class OutputDevice : public EventSink {}; 15 | 16 | }// namespace fredemmott::inputmapping 17 | -------------------------------------------------------------------------------- /lib/include/cpp-remapper/EventSink.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | namespace fredemmott::inputmapping { 11 | 12 | class EventSink { 13 | public: 14 | virtual ~EventSink(); 15 | virtual void flush() = 0; 16 | }; 17 | 18 | }// namespace fredemmott::inputmapping 19 | -------------------------------------------------------------------------------- /lib/MappableOutput.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #include 10 | 11 | namespace fredemmott::inputmapping { 12 | 13 | MappableOutput::MappableOutput() { 14 | } 15 | 16 | MappableOutput::~MappableOutput() { 17 | } 18 | 19 | }// namespace fredemmott::inputmapping 20 | -------------------------------------------------------------------------------- /tests/FunctionSink_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #include 10 | 11 | #include "tests.h" 12 | 13 | using namespace fredemmott::inputmapping; 14 | 15 | TEST_CASE("FunctionSink") { 16 | Axis::Value value = -1; 17 | 18 | TestAxis axis; 19 | axis >> [&value](Axis::Value newValue) { value = newValue; }; 20 | axis.emit(1337); 21 | REQUIRE(value == 1337); 22 | } 23 | -------------------------------------------------------------------------------- /lib/ButtonToAxis.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #include 9 | 10 | namespace fredemmott::inputmapping { 11 | 12 | ButtonToAxis::ButtonToAxis(Axis::Value falseValue, Axis::Value trueValue) 13 | : mFalse(falseValue), mTrue(trueValue) { 14 | } 15 | 16 | void ButtonToAxis::map(bool value) { 17 | emit(value ? mTrue : mFalse); 18 | } 19 | 20 | }// namespace fredemmott::inputmapping 21 | -------------------------------------------------------------------------------- /lib/Percent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #include 9 | 10 | namespace fredemmott::inputmapping { 11 | 12 | Percent::Percent(uint8_t value) : mValue(value) { 13 | } 14 | 15 | uint8_t Percent::value() const noexcept { 16 | return mValue; 17 | } 18 | 19 | Percent operator"" _percent(unsigned long long value) { 20 | return Percent(value); 21 | } 22 | 23 | }// namespace fredemmott::inputmapping 24 | -------------------------------------------------------------------------------- /lib/include/cpp-remapper/EventSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | #define _WIN32_LEAN_AND_MEAN 11 | #include 12 | 13 | namespace fredemmott::inputmapping { 14 | 15 | class EventSource { 16 | protected: 17 | EventSource(); 18 | 19 | public: 20 | virtual ~EventSource(); 21 | virtual HANDLE getHandle() = 0; 22 | virtual void poll() = 0; 23 | }; 24 | }// namespace fredemmott::inputmapping 25 | -------------------------------------------------------------------------------- /tests/FunctionTransform_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #include 10 | 11 | #include "tests.h" 12 | 13 | using namespace fredemmott::inputmapping; 14 | 15 | TEST_CASE("FunctionTransform") { 16 | Axis::Value value = -1; 17 | 18 | TestAxis axis; 19 | axis >> [](Axis::Value value) { return Axis::MAX - value; } >> &value; 20 | axis.emit(Axis::MAX); 21 | REQUIRE(value == 0); 22 | } 23 | -------------------------------------------------------------------------------- /lib/include/cpp-remapper/MappableOutput.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace fredemmott::inputmapping { 13 | 14 | class OutputDevice; 15 | 16 | class MappableOutput { 17 | protected: 18 | MappableOutput(); 19 | 20 | public: 21 | virtual ~MappableOutput(); 22 | virtual std::shared_ptr getDevice() const = 0; 23 | }; 24 | 25 | }// namespace fredemmott::inputmapping 26 | -------------------------------------------------------------------------------- /lib/include/cpp-remapper/Percent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace fredemmott::inputmapping { 13 | 14 | class Percent final { 15 | private: 16 | uint8_t mValue; 17 | 18 | public: 19 | explicit Percent(uint8_t value); 20 | uint8_t value() const noexcept; 21 | }; 22 | 23 | Percent operator"" _percent(unsigned long long value); 24 | 25 | }// namespace fredemmott::inputmapping 26 | -------------------------------------------------------------------------------- /lib/AnyOfButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | 9 | #include 10 | 11 | namespace fredemmott::inputmapping { 12 | 13 | void AnyOfButton::map(bool pressed) { 14 | if (pressed) { 15 | mPressed++; 16 | if (mPressed == 1) { 17 | emit(true); 18 | } 19 | return; 20 | } 21 | 22 | mPressed--; 23 | if (mPressed == 0) { 24 | emit(false); 25 | } 26 | } 27 | 28 | }// namespace fredemmott::inputmapping 29 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_cppremapper_executable( 2 | test 3 | AnyOfButton_test.cpp 4 | AxisCurve_test.cpp 5 | AxisToButtons_test.cpp 6 | AxisToHat_test.cpp 7 | AxisTrimmer_test.cpp 8 | ButtonToAxis_test.cpp 9 | CompositeSink_test.cpp 10 | FakeClock.cpp 11 | FunctionSink_test.cpp 12 | FunctionTransform_test.cpp 13 | HatToButtons_test.cpp 14 | LatchedToMomentaryButton_test.cpp 15 | MomentaryToLatchedButton_test.cpp 16 | Profile_test.cpp 17 | Shift_test.cpp 18 | ShortPressLongPress_test.cpp 19 | SquareDeadzone_test.cpp 20 | connections_test.cpp 21 | test.cpp 22 | ) 23 | 24 | target_link_libraries( 25 | test 26 | PRIVATE 27 | ThirdParty-Catch2 28 | LibCppRemapper 29 | ) 30 | -------------------------------------------------------------------------------- /third-party/favhidclient.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | find_package(Git) 3 | 4 | set(FAVHID_REVISION "88f3f8f874b5587f473dd9ae78cb7abb7076d669") 5 | FetchContent_Declare( 6 | favhidclient 7 | GIT_REPOSITORY https://github.com/fredemmott/favhid-client.git 8 | GIT_TAG main 9 | PATCH_COMMAND "${GIT_EXECUTABLE}" reset --hard "${FAVHID_REVISION}" 10 | EXCLUDE_FROM_ALL 11 | ) 12 | 13 | FetchContent_MakeAvailable(favhidclient) 14 | 15 | # Build against the same version. Generally a good idea, but especially needed 16 | # for /await compat with the obsolete toolchain on github actions 17 | target_link_libraries(favhid PUBLIC ThirdParty-CppWinRT) 18 | 19 | add_library(ThirdParty-FAVHIDClient ALIAS favhid) -------------------------------------------------------------------------------- /tests/tests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020-present, Fred Emmott 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the ISC license found in the LICENSE file 6 | * in the root directory of this source tree. 7 | */ 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace fredemmott::inputmapping { 16 | 17 | template 18 | class TestInput final : public Source { 19 | public: 20 | using Source::emit; 21 | }; 22 | using TestAxis = TestInput; 23 | using TestButton = TestInput