-
-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for external bluetooth devices #535
base: master
Are you sure you want to change the base?
Changes from all commits
e8dc11c
2243af8
e6d6221
0bdc7f6
3c1641a
729efb5
77959fa
fb26e5a
c2123c3
7dc70a2
fea52db
4cdcb8a
eab5fd3
13ee3a1
606158f
17f1b6a
83cc00b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -403,6 +403,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp | |
include/audio/audio_interpolation.hpp include/audio/hle_mixer.hpp include/audio/dsp_simd.hpp | ||
include/services/dsp_firmware_db.hpp include/frontend_settings.hpp include/fs/archive_twl_photo.hpp | ||
include/fs/archive_twl_sound.hpp include/fs/archive_card_spi.hpp include/services/ns.hpp | ||
include/external_haptics_manager.hpp | ||
) | ||
|
||
cmrc_add_resource_library( | ||
|
@@ -432,6 +433,11 @@ if(ENABLE_LUAJIT AND NOT ANDROID) | |
|
||
add_subdirectory(third_party/libuv) | ||
target_link_libraries(AlberCore PRIVATE uv_a) | ||
|
||
include_directories(third_party/open-bp-cpp/include) | ||
include_directories(third_party/open-bp-cpp/third_party/IXWebSocket/ixwebsocket) | ||
add_subdirectory(third_party/open-bp-cpp) | ||
target_link_libraries(AlberCore PRIVATE buttplugCpp) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This library doesn't really feel as a core component of Alber to justify being linked to the core library. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't care |
||
endif() | ||
|
||
set(GL_CONTEXT_SOURCE_FILES "") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#pragma once | ||
|
||
#include <chrono> | ||
#include <cstdio> | ||
#include <string> | ||
#include <thread> | ||
#include <vector> | ||
|
||
#include "buttplugclient.h" | ||
|
||
class ExternalHapticsManager { | ||
Client client; | ||
std::vector<DeviceClass> devices; | ||
SensorClass sensors; | ||
|
||
public: | ||
ExternalHapticsManager() : client("ws://127.0.0.1", 12345) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't hardcode the address/port like that. More so, what if I want to receive haptic inputs from people all around the globe, do I have to modify the code myself to change the ip address my haptic device is hosted on? What is this, dwm? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This adds buttplug support not e-sex support bro There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what that b word is or what e-sex is, please address the review comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
fucking e-virgin There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding onto @OFFTKP's suggestion I would suggest adding UPnP support if the IP is 127.0.0.1 to automatically port forward the rumble device if it is hosted on the same networks and registering the public IP in a real time database such as firebase for any Panda3DS user to connect to. |
||
|
||
void connect() { | ||
client.connect([](const mhl::Messages message) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the point of const when we are copying a value over anyway? |
||
switch (message.messageType) { | ||
case mhl::MessageTypes::DeviceList: std::printf("Device List callback\n"); break; | ||
case mhl::MessageTypes::DeviceAdded: std::printf("Device List callback\n"); break; | ||
case mhl::MessageTypes::ServerInfo: std::printf("Server info callback\n"); break; | ||
case mhl::MessageTypes::DeviceRemoved: std::printf("Device Removed callback\n"); break; | ||
case mhl::MessageTypes::SensorReading: std::printf("Sensor reading callback\n"); break; | ||
default: std::printf("Unknown message"); | ||
} | ||
}); | ||
} | ||
|
||
void requestDeviceList() { client.requestDeviceList(); } | ||
void startScan() { client.startScan(); } | ||
void stopScan() { client.stopScan(); } | ||
void stopAllDevices() { client.stopAllDevices(); } | ||
|
||
void getDevices() { devices = client.getDevices(); } | ||
void getSensors() { sensors = client.getSensors(); } | ||
|
||
void sendScalar(int index, double value) { | ||
if (index < devices.size()) { | ||
client.sendScalar(devices[index], value); | ||
} | ||
} | ||
|
||
void stopDevice(int index) { | ||
if (index < devices.size()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would probably trigger a signed unsigned comparison warning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't care wtf |
||
client.stopDevice(devices[index]); | ||
} | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
#include <teakra/disassembler.h> | ||
|
||
#include <array> | ||
#include <memory> | ||
|
||
#include "capstone.hpp" | ||
#include "emulator.hpp" | ||
|
@@ -11,6 +12,8 @@ | |
extern "C" { | ||
#include "luv.h" | ||
} | ||
|
||
#include "external_haptics_manager.hpp" | ||
#endif | ||
|
||
void LuaManager::initialize() { | ||
|
@@ -268,6 +271,80 @@ static int disassembleTeakThunk(lua_State* L) { | |
return 1; | ||
} | ||
|
||
#ifndef __ANDROID__ | ||
// Haptics functions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Meaningless comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't care There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you care a little |
||
|
||
namespace Haptics { | ||
std::unique_ptr<ExternalHapticsManager> hapticsManager = nullptr; | ||
|
||
static int initHapticsThunk(lua_State* L) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Static functions in global scope are deprecated in favor of putting the function in an unnamed namespace instead |
||
if (hapticsManager == nullptr) { | ||
hapticsManager.reset(new ExternalHapticsManager()); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
#define HAPTICS_THUNK(func) \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. X macros are bad because they enable you to essentially have a very easy and portable way to generate boilerplate code and reduce duplicated code, thus leading to less source code cluttering. Wait why did I say they are bad? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lines of code = performance |
||
static int func##Thunk(lua_State* L) { \ | ||
if (hapticsManager != nullptr) { \ | ||
hapticsManager->func(); \ | ||
} \ | ||
\ | ||
return 0; \ | ||
} | ||
|
||
HAPTICS_THUNK(startScan) | ||
HAPTICS_THUNK(stopScan) | ||
HAPTICS_THUNK(connect) | ||
HAPTICS_THUNK(requestDeviceList) | ||
HAPTICS_THUNK(getDevices) | ||
HAPTICS_THUNK(getSensors) | ||
HAPTICS_THUNK(stopAllDevices) | ||
#undef HAPTICS_THUNK | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't match indentation of #define There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't care |
||
|
||
static int sendScalarThunk(lua_State* L) { | ||
const int device = (int)lua_tonumber(L, 1); | ||
const auto value = lua_tonumber(L, 2); | ||
|
||
if (hapticsManager != nullptr) { | ||
hapticsManager->sendScalar(device, value); | ||
} | ||
|
||
return 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Magic number There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sir this is how Lua thunks work, you return the number of return values |
||
} | ||
|
||
static int stopDeviceThunk(lua_State* L) { | ||
const int device = (int)lua_tonumber(L, 1); | ||
|
||
if (hapticsManager != nullptr) { | ||
hapticsManager->stopDevice(device); | ||
} | ||
|
||
return 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another magic number |
||
} | ||
|
||
// clang-format off | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What a tragedy |
||
static constexpr luaL_Reg functions[] = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See comment above, also static constexpr doesn't make much sense to me anyway There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. constexpr makes it a constant expresison, static guarantees that it's allocated in static storage instead of copied on the stack when the function runs. This is why any LUTs you declare in a function should be declared as static constexpr and NOT plain constexpr. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't in a function so it's gonna go in static storage anyway. However we should keep it as constexpr (even if it does literally nothing) so that we can claim we use modern C++. Also you missed a chance to use the X macros you love so much: #define X(name) { #name, name##Thunk }, |
||
{ "initHaptics", initHapticsThunk }, | ||
{ "startScan", startScanThunk }, | ||
{ "stopScan", stopScanThunk }, | ||
{ "connect", connectThunk }, | ||
{ "requestDeviceList", requestDeviceListThunk }, | ||
{ "getDevices", getDevicesThunk }, | ||
{ "getSensors", getSensorsThunk }, | ||
{ "stopAllDevices", stopAllDevicesThunk }, | ||
{ "sendScalar", sendScalarThunk }, | ||
{ "stopDevice", stopDeviceThunk }, | ||
}; | ||
// clang-format on | ||
|
||
void registerFunctions(lua_State* L) { | ||
luaL_register(L, "HAPTICS", functions); | ||
} | ||
} // namespace Haptics | ||
#endif | ||
|
||
// clang-format off | ||
static constexpr luaL_Reg functions[] = { | ||
{ "__read8", read8Thunk }, | ||
|
@@ -345,6 +422,20 @@ void LuaManager::initializeThunks() { | |
ButtonLeft = __ButtonLeft, | ||
ButtonRight= __ButtonRight, | ||
} | ||
|
||
Buzz = { | ||
initHaptics = function() HAPTICS.initHaptics() end, | ||
startScan = function() HAPTICS.startScan() end, | ||
stopScan = function() HAPTICS.stopScan() end, | ||
connect = function() HAPTICS.connect() end, | ||
requestDeviceList = function() HAPTICS.requestDeviceList() end, | ||
getDevices = function() HAPTICS.getDevices() end, | ||
getSensors = function() HAPTICS.getSensors() end, | ||
stopAllDevices = function() HAPTICS.stopAllDevices() end, | ||
|
||
sendScalar = function(device, value) HAPTICS.sendScalar(device, value) end, | ||
stopDevice = function(device) HAPTICS.stopDevice(device) end, | ||
} | ||
)"; | ||
|
||
auto addIntConstant = [&]<typename T>(T x, const char* name) { | ||
|
@@ -353,6 +444,10 @@ void LuaManager::initializeThunks() { | |
}; | ||
|
||
luaL_register(L, "GLOBALS", functions); | ||
#ifndef __ANDROID__ | ||
Haptics::registerFunctions(L); | ||
#endif | ||
|
||
// Add values for event enum | ||
addIntConstant(LuaEvent::Frame, "__Frame"); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
############################################################################### | ||
# Set default behavior to automatically normalize line endings. | ||
############################################################################### | ||
* text=auto | ||
|
||
############################################################################### | ||
# Set default behavior for command prompt diff. | ||
# | ||
# This is need for earlier builds of msysgit that does not have it on by | ||
# default for csharp files. | ||
# Note: This is only used by command line | ||
############################################################################### | ||
#*.cs diff=csharp | ||
|
||
############################################################################### | ||
# Set the merge driver for project and solution files | ||
# | ||
# Merging from the command prompt will add diff markers to the files if there | ||
# are conflicts (Merging from VS is not affected by the settings below, in VS | ||
# the diff markers are never inserted). Diff markers may cause the following | ||
# file extensions to fail to load in VS. An alternative would be to treat | ||
# these files as binary and thus will always conflict and require user | ||
# intervention with every merge. To do so, just uncomment the entries below | ||
############################################################################### | ||
#*.sln merge=binary | ||
#*.csproj merge=binary | ||
#*.vbproj merge=binary | ||
#*.vcxproj merge=binary | ||
#*.vcproj merge=binary | ||
#*.dbproj merge=binary | ||
#*.fsproj merge=binary | ||
#*.lsproj merge=binary | ||
#*.wixproj merge=binary | ||
#*.modelproj merge=binary | ||
#*.sqlproj merge=binary | ||
#*.wwaproj merge=binary | ||
|
||
############################################################################### | ||
# behavior for image files | ||
# | ||
# image files are treated as binary by default. | ||
############################################################################### | ||
#*.jpg binary | ||
#*.png binary | ||
#*.gif binary | ||
|
||
############################################################################### | ||
# diff behavior for common document formats | ||
# | ||
# Convert binary document formats to text before diffing them. This feature | ||
# is only available from the command line. Turn it on by uncommenting the | ||
# entries below. | ||
############################################################################### | ||
#*.doc diff=astextplain | ||
#*.DOC diff=astextplain | ||
#*.docx diff=astextplain | ||
#*.DOCX diff=astextplain | ||
#*.dot diff=astextplain | ||
#*.DOT diff=astextplain | ||
#*.pdf diff=astextplain | ||
#*.PDF diff=astextplain | ||
#*.rtf diff=astextplain | ||
#*.RTF diff=astextplain |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Prerequisites | ||
*.d | ||
|
||
# Compiled Object files | ||
*.slo | ||
*.lo | ||
*.o | ||
*.obj | ||
|
||
# Precompiled Headers | ||
*.gch | ||
*.pch | ||
|
||
# Compiled Dynamic libraries | ||
*.so | ||
*.dylib | ||
*.dll | ||
|
||
# Fortran module files | ||
*.mod | ||
*.smod | ||
|
||
# Compiled Static libraries | ||
*.lai | ||
*.la | ||
*.a | ||
*.lib | ||
|
||
# Executables | ||
*.exe | ||
*.out | ||
*.app | ||
/.vs | ||
/out/build/x64-debug | ||
/CMakeFiles | ||
/_3rdParty | ||
/CMakeCache.txt | ||
/cmake_install.cmake | ||
/Makefile | ||
/buttplugCpp |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# CMakeList.txt : CMake project for buttplugCpp, include source and define | ||
# project specific logic here. | ||
# | ||
cmake_minimum_required (VERSION 3.8) | ||
|
||
# Enable Hot Reload for MSVC compilers if supported. | ||
if (POLICY CMP0141) | ||
cmake_policy(SET CMP0141 NEW) | ||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>") | ||
endif() | ||
|
||
project(buttplugCpp) | ||
|
||
# Add source to this project's executable. | ||
|
||
file(GLOB SRC_FILES | ||
"source/*.cpp" | ||
"include/*.h" | ||
"include/*.hpp" | ||
) | ||
|
||
add_library(buttplugCpp STATIC ${SRC_FILES}) | ||
|
||
set(USE_ZLIB FALSE) | ||
target_include_directories(buttplugCpp PUBLIC third_party/IXWebSocket/ixwebsocket) | ||
target_include_directories(buttplugCpp PUBLIC include) | ||
add_subdirectory(third_party/IXWebSocket) | ||
|
||
find_package(Threads REQUIRED) | ||
target_link_libraries(buttplugCpp PUBLIC ixwebsocket::ixwebsocket Threads::Threads) | ||
|
||
if (CMAKE_VERSION VERSION_GREATER 3.12) | ||
set_property(TARGET buttplugCpp PROPERTY CXX_STANDARD 11) | ||
endif() | ||
# TODO: Add tests and install targets if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You added this as a submodule, but not open-bp-cpp. We prefer to store stuff as submodules here so that when githubs go private we don't suffer any damages. Actually wait, that would have the opposite effect. What was I saying? Oh please add open-bp-cpp as a submodule instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OPEN BP CPP IS HEAVILY MODIFIED AS I MADE IT GOOD WHILE IT WAS HORRIBLE BEFORE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sorry but I am not going to go through 20 thousand lines of code to make sure you didn't add a backdoor (heh get it?) somewhere in the program.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dun geddit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well you see, prior this year we had some "guys" that tried to implement a backdoor in the OSS project named XZ. Here, OFFTKP wants to make sure that the program stays secure. In order to do that, every PR that adds code must be analyzed by hand to prevent any attack of this kind. Reviewing code is an operation that take an exponential amount of time. The more line there is to review, the more time it takes. I totally understand that OFFTKP does not have the required time to analyze 20K lines of code. Only peoples employed in an enterprise would do this. If he/she is a hobbyist or a developer doing this on his/her free time, then he/she may not have this time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://en.m.wikipedia.org/wiki/Singular_they
I agree, either they (the author of this PR) rewrite to use the "official" branch of the library or they try to make a PR to make their branch of the library merged to the library itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I am not en English people so I didn't know it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A true 10X programmer like @OFFTKP would have no problem with 20K lines of code. A real 69X programmer like me would just look at the diff between upstream and my vendored version in a text editor 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a fellow 69X programmer, I confirmed that the files added was 100x improvement modification from the original https://github.com/dumbowumbo/buttplugCpp repository (in which is the officially supported binding of the Buttplug library) that is totally harmless and definitely not a backdoor.