mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-17 19:00:48 +02:00
The Android client drops HapticService:SetMotor on the Gamepad1 LeftHand and RightHand motors: its haptics backend only consumes Large and Small. VR games such as VR Hands drive those motors, so they never vibrated. - Interpose HapticService::SetMotor through its reflection descriptor, call the original, and forward Gamepad1 LeftHand/RightHand to OpenXR. The descriptor and the engine's intensity reader are found by pattern at load, for both the 2998 (tuple span) and 3222 (shared tuple) reader ABIs. The held level renews a 50 ms lease every presented frame. - Report the hand motors at x = -1/+1 in GetMotors. Positional HapticEffects aim at a hand there with a 0.5 radius (VOXEL DESTRUCT 2 does), so at +-0.2 every effect mixed to zero. - Play SetMotorState buffers sample by sample with trailing silence trimmed. Roblox sends 100 x 25 ms look-ahead buffers; taking the peak for the whole buffer turned a short bump into 2.5 s at full strength. - Stop vibrating from the DebugDeviceVR haptic slot. The engine pulls it every frame but with each mix buffer's first sample, held about a second, so it duplicated the buffers as a long buzz. - Enable SupportGenericHapticsOnVR and FixRegisterMotors with the other haptic flags.
48 lines
1.4 KiB
C++
48 lines
1.4 KiB
C++
#ifndef MOCKTAIL_RUNTIME_ROBLOX_HAPTIC_PROTOCOL_BRIDGE_H_
|
|
#define MOCKTAIL_RUNTIME_ROBLOX_HAPTIC_PROTOCOL_BRIDGE_H_
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "runtime/roblox_message_bus_request_bridge.h"
|
|
|
|
namespace mocktail {
|
|
namespace runtime {
|
|
|
|
using HapticSinkFn = std::function<void(int hand, float amplitude,
|
|
uint64_t duration_ns, float frequency_hz)>;
|
|
using HapticStopFn = std::function<void(int hand)>;
|
|
using HapticStateSyncFn = std::function<void(JNIEnv* env)>;
|
|
|
|
class HapticWaveformPlayer;
|
|
|
|
class RobloxHapticProtocolBridge final {
|
|
public:
|
|
RobloxHapticProtocolBridge(
|
|
JniEnvironmentProvider environment,
|
|
RobloxMessageBusSymbols symbols,
|
|
RobloxMessageBusObjects objects,
|
|
HapticSinkFn haptic_sink = nullptr,
|
|
HapticStopFn haptic_stop = nullptr,
|
|
HapticStateSyncFn haptic_state_sync = nullptr);
|
|
~RobloxHapticProtocolBridge();
|
|
|
|
Status Initialize();
|
|
Status Shutdown();
|
|
|
|
static std::string GetMotorsJson();
|
|
// True during a VR session; main() sets MOCKTAIL_VR_ENABLED to 0 when VR
|
|
// cannot start, so the bridge stays off for desktop play.
|
|
static bool EnabledForThisSession();
|
|
|
|
private:
|
|
std::shared_ptr<HapticWaveformPlayer> player_;
|
|
std::unique_ptr<RobloxMessageBusRequestBridge> bridge_;
|
|
};
|
|
|
|
} // namespace runtime
|
|
} // namespace mocktail
|
|
#endif
|