1 /* 2 DS5_Output.h is part of DualSenseWindows 3 https://github.com/Ohjurot/DualSense-Windows 4 5 Contributors of this file: 6 11.2020 Ludwig Füchsl 7 8 Licensed under the MIT License (To be found in repository root directory) 9 */ 10 module ds5w.ds5output; 11 12 import ds5w.dswapi; 13 import ds5w.device; 14 import ds5w.ds5state; 15 16 import std.algorithm; 17 18 void createHidOutputBuffer(ubyte* hidOutBuffer, DS5OutputState* ptrOutputState) 19 { 20 // Feature mask 21 hidOutBuffer[0x00] = 0xFF; 22 hidOutBuffer[0x01] = 0xF7; 23 24 // Rumbel motors 25 hidOutBuffer[0x02] = ptrOutputState.rightRumble; 26 hidOutBuffer[0x03] = ptrOutputState.leftRumble; 27 28 // Mic led 29 hidOutBuffer[0x08] = cast(ubyte) ptrOutputState.microphoneLed; 30 31 // Player led 32 hidOutBuffer[0x2B] = ptrOutputState.playerLeds.bitmask; 33 if (ptrOutputState.playerLeds.playerLedFade) 34 { 35 hidOutBuffer[0x2B] &= ~(0x20); 36 } 37 else 38 { 39 hidOutBuffer[0x2B] |= 0x20; 40 } 41 42 // Player led brightness 43 hidOutBuffer[0x26] = 0x03; 44 hidOutBuffer[0x29] = ptrOutputState.disableLeds ? 0x01 : 0x2; 45 hidOutBuffer[0x2A] = ptrOutputState.playerLeds.brightness; 46 47 // Lightbar 48 hidOutBuffer[0x2C] = ptrOutputState.lightbar.r; 49 hidOutBuffer[0x2D] = ptrOutputState.lightbar.g; 50 hidOutBuffer[0x2E] = ptrOutputState.lightbar.b; 51 52 // Adaptive Triggers 53 processTrigger(&ptrOutputState.leftTriggerEffect, &hidOutBuffer[0x15]); 54 processTrigger(&ptrOutputState.rightTriggerEffect, &hidOutBuffer[0x0A]); 55 } 56 57 void processTrigger(TriggerEffect* ptrEffect, ubyte* buffer) 58 { 59 // Switch on effect 60 switch (ptrEffect.effectType) 61 { 62 // Continious 63 case TriggerEffectType.ContinuousResitance: 64 // Mode 65 buffer[0x00] = 0x01; 66 // Parameters 67 buffer[0x01] = ptrEffect.Continuous.startPosition; 68 buffer[0x02] = ptrEffect.Continuous.force; 69 70 break; 71 72 // Section 73 case TriggerEffectType.SectionResitance: 74 // Mode 75 buffer[0x00] = 0x02; 76 // Parameters 77 buffer[0x01] = ptrEffect.Continuous.startPosition; 78 buffer[0x02] = ptrEffect.Continuous.force; 79 80 break; 81 82 // EffectEx 83 case TriggerEffectType.EffectEx: 84 // Mode 85 buffer[0x00] = 0x02 | 0x20 | 0x04; 86 // Parameters 87 buffer[0x01] = 0xFF - ptrEffect.EffectEx.startPosition; 88 // Keep flag 89 if (ptrEffect.EffectEx.keepEffect) 90 { 91 buffer[0x02] = 0x02; 92 } 93 // Forces 94 buffer[0x04] = ptrEffect.EffectEx.beginForce; 95 buffer[0x05] = ptrEffect.EffectEx.middleForce; 96 buffer[0x06] = ptrEffect.EffectEx.endForce; 97 // Frequency 98 buffer[0x09] = max(ubyte(1), cast(ubyte)(ptrEffect.EffectEx.frequency / 2)); 99 100 break; 101 102 // Calibrate 103 case TriggerEffectType.Calibrate: 104 // Mode 105 buffer[0x00] = 0xFC; 106 107 break; 108 109 // No resistance / default 110 case TriggerEffectType.NoResitance: 111 default: // All zero 112 buffer[0x00] = 0x00; 113 buffer[0x01] = 0x00; 114 buffer[0x02] = 0x00; 115 116 break; 117 } 118 }