public bool Do(VirtualFFBPacket Packet) { if (this.Packets.Count > 60) { this.PacketCleaning(); } if (this.Effects.Count > 256) { this.EffectCleaning(); } bool flag = true; if (//!this.UpdateBaseParams(Packet) && !this.CreateBaseParams(Packet) && //!this.UpdateTypeSpecificParams(Packet) && //!this.UpdateEnvelopeParams(Packet) && !this.EffectPlayback(Packet) && !this.GainControl(Packet) && !this.DeviceControl(Packet) && !this.MiscControl(Packet)) { flag = false; } this.Packets.Add(Packet); if (flag) { this.Effects.Sort(new Comparison <VirtualFFBEffect>(VirtualFFBState.EffectComparison_UpdateDateTime)); return(true); } return(false); }
public static void FFBPacketCallback(IntPtr data, object userData) { if (data != IntPtr.Zero) { Task.Run(() => { VirtualFFBPacket packet = ProcessFFBPacket(data, userData); packets.Enqueue(packet, packet.GetPriority()); }); } }
private bool EffectDispose(VirtualFFBPacket Packet, VirtualFFBEffect Effect) { if (Packet.BlockIndex == Effect.Index) { Effect.Dispose(); Effect.Packet = Packet; return(true); } return(false); }
private bool GainControl(VirtualFFBPacket Packet) { if (Packet._FFBPType == FFBPType.PT_GAINREP) { this.Gain = (int)Packet.Gain * 10000 / 255; Packet.Handled = true; return(true); } return(false); }
private bool EffectPlayback(VirtualFFBPacket Packet, VirtualFFBEffect Effect) { if (Packet._FFBPType == FFBPType.PT_EFOPREP && (int)Packet.FFB_EFF_OP.EffectBlockIndex == Effect.Index && Effect.Status != EffectStatus.None && Effect.Parameters.TriggerButton == -1) { Effect.UpdateStatus(); switch (Packet.FFB_EFF_OP.EffectOp) { case FFBOP.EFF_START: if (Effect.Status != EffectStatus.Playing) { Effect.LoopCount = (int)Packet.FFB_EFF_OP.LoopCount; Effect.Solo = false; this.StartEffect(Effect); Effect.Packet = Packet; Packet.Handled = true; return(true); } break; case FFBOP.EFF_SOLO: if (Effect.Status != EffectStatus.Playing) { for (int i = 0; i < this.Effects.Count; i++) { if (this.Effects[i] != Effect) { this.StopEffect(this.Effects[i]); this.Effects[i].Packet = Packet; } } Effect.LoopCount = (int)Packet.FFB_EFF_OP.LoopCount; Effect.Solo = true; this.StartEffect(Effect); Effect.Packet = Packet; Packet.Handled = true; return(true); } break; case FFBOP.EFF_STOP: if (Effect.Status == EffectStatus.Playing) { this.StopEffect(Effect); Effect.Packet = Packet; Packet.Handled = true; return(true); } break; } } return(false); }
private bool DeviceControl(VirtualFFBPacket Packet) { if (Packet._FFBPType == FFBPType.PT_CTRLREP) { switch (Packet.FFB_CTRL) { case FFB_CTRL.CTRL_ENACT: this.EnabledActuators = true; break; case FFB_CTRL.CTRL_DISACT: this.EnabledActuators = false; break; case FFB_CTRL.CTRL_STOPALL: for (int i = 0; i < this.Effects.Count; i++) { if (this.Effects[i].Status == EffectStatus.Playing && this.Effects[i].Parameters.TriggerButton == -1) { this.Effects[i].Packet = Packet; this.StopEffect(this.Effects[i]); } } this.DevicePause = false; break; case FFB_CTRL.CTRL_DEVRST: for (int j = 0; j < this.Effects.Count; j++) { if (this.Effects[j].Status == EffectStatus.Playing && this.Effects[j].Parameters.TriggerButton == -1) { this.Effects[j].Packet = Packet; this.StopEffect(this.Effects[j]); } } this.EnabledActuators = false; this.Effects.Clear(); this.DevicePause = false; this.EnabledActuators = true; break; case FFB_CTRL.CTRL_DEVPAUSE: this.DevicePause = true; break; case FFB_CTRL.CTRL_DEVCONT: this.DevicePause = false; break; } Packet.Handled = true; return(true); } return(false); }
private bool MiscControl(VirtualFFBPacket Packet) { bool flag = false; switch (Packet._FFBPType) { case FFBPType.PT_BLKFRREP: flag = this.EffectDispose(Packet); break; } Packet.Handled = flag; return(flag); }
private bool EffectPlayback(VirtualFFBPacket Packet) { if (this.DevicePause) { return(false); } bool result = false; for (int i = this.Effects.Count - 1; i >= 0; i--) { if (this.EffectPlayback(Packet, this.Effects[i])) { result = true; break; } } return(result); }
private bool CreateBaseParams(VirtualFFBPacket Packet) { if (Packet._FFBPType != FFBPType.PT_EFFREP) { return(false); } if (this.DevicePause) { return(false); } EffectParametersEx baseEffectParameters = GetBaseEffectParameters(Packet.FFB_EFF_REPORT); VirtualFFBEffect vJoyFFBEffect = new VirtualFFBEffect(); vJoyFFBEffect.Parameters = baseEffectParameters; vJoyFFBEffect.Index = Packet.BlockIndex; int num = 0; for (int i = this.Packets.Count - 1; i >= 0; i--) { TimeSpan timeSpan = vJoyFFBEffect.CreationTime - this.Packets[i].CreationTime; if (this.Packets[i]._FFBPType == FFBPType.PT_EFFREP || timeSpan.TotalSeconds > 5.0) { num = i; break; } } bool flag = false; //for (int j = num; j < this.Packets.Count; j++) { //this.UpdateEnvelopeParams(this.Packets[j], vJoyFFBEffect); //if (this.UpdateTypeSpecificParams(this.Packets[j], vJoyFFBEffect)) { // flag = true; //} //} if (flag) { vJoyFFBEffect.Status = EffectStatus.Idle; } vJoyFFBEffect.Packet = Packet; this.Effects.Add(vJoyFFBEffect); Packet.Handled = true; return(true); }
public VirtualFFBEffect() { DateTime now = DateTime.Now; this.CreationTime = now; this.UpdateTime = now; this.BaseUpdateTime = now; this.StartTime = DateTime.MinValue; this.StopTime = DateTime.MinValue; this.Status = EffectStatus.None; this.Downloaded = false; this.Parameters = new EffectParametersEx(); this.ConditionX = false; this.ConditionY = false; this.Solo = false; this.LoopCount = 1; this.Packet = null; this.Index = 0; }
public static void FFBProcessingThread() { try { logger.Info("Starting FFBProcThread"); while (true) { while (packets.Count > 0) { VirtualFFBPacket packet = packets.Dequeue(); handlers[packet.ID]?.Invoke(packet); //FFBDataReceived?.Invoke(packets.Dequeue()); //Thread.Sleep(1); } Thread.Sleep(100); //newDataEvent.WaitOne(); } } catch (ThreadAbortException) { logger.Info("Stopping FFBProcThread"); } catch (Exception ex) { logger.Warn($"FFBProcThread WTF {ex}"); } finally { packets.Clear(); } }
public static VirtualFFBPacket ProcessFFBPacket(IntPtr data, object userData) { VirtualFFBPacket FFBPacket = new VirtualFFBPacket(); if (joystick.Ffb_h_Type(data, ref FFBPacket._FFBPType) == ERROR_SUCCESS) { joystick.Ffb_h_DeviceID(data, ref FFBPacket.ID); switch (FFBPacket._FFBPType) { case FFBPType.PT_EFFREP: // Effect Report (also named EFFECT_CONST) if (joystick.Ffb_h_Eff_Report(data, ref FFBPacket.FFB_EFF_REPORT) == ERROR_SUCCESS) { FFBPacket.BlockIndex = FFBPacket.FFB_EFF_REPORT.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Effect Report"); logger.Trace(FFBPacket.GenerateEffectInfo()); } break; case FFBPType.PT_ENVREP: // Envelope Report if (joystick.Ffb_h_Eff_Envlp(data, ref FFBPacket.FFB_EFF_ENVLP) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_ENVLP.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Envelope Report"); } break; case FFBPType.PT_CONDREP: // Condition Report !! if (joystick.Ffb_h_Eff_Cond(data, ref FFBPacket.FFB_EFF_COND) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_COND.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Condition Report"); StringBuilder dat = new StringBuilder(); dat.AppendFormat($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Condition Report\n"); dat.AppendFormat($"\t EBI={FFBPacket.FFB_EFF_COND.EffectBlockIndex}\n"); dat.AppendFormat($"\t Center={FFBPacket.FFB_EFF_COND.CenterPointOffset}\n"); dat.AppendFormat($"\t DeadBand={FFBPacket.FFB_EFF_COND.DeadBand}\n"); dat.AppendFormat($"\t isY={FFBPacket.FFB_EFF_COND.isY}\n"); dat.AppendFormat($"\t NegCoeff={FFBPacket.FFB_EFF_COND.NegCoeff}\n"); dat.AppendFormat($"\t NegSatur={FFBPacket.FFB_EFF_COND.NegSatur}\n"); dat.AppendFormat($"\t PosCoeff={FFBPacket.FFB_EFF_COND.PosCoeff}\n"); dat.AppendFormat($"\t PosSatur={FFBPacket.FFB_EFF_COND.PosSatur}"); logger.Trace(dat); } break; case FFBPType.PT_PRIDREP: // Periodic Report if (joystick.Ffb_h_Eff_Period(data, ref FFBPacket.FFB_EFF_PERIOD) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_PERIOD.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Periodic Report"); StringBuilder dat = new StringBuilder(); dat.AppendFormat($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Periodic Report\n"); dat.AppendFormat($"\t EBI={FFBPacket.FFB_EFF_PERIOD.EffectBlockIndex}\n"); dat.AppendFormat($"\t Magnitude={FFBPacket.FFB_EFF_PERIOD.Magnitude}\n"); dat.AppendFormat($"\t Offset={FFBPacket.FFB_EFF_PERIOD.Offset}\n"); dat.AppendFormat($"\t Period={FFBPacket.FFB_EFF_PERIOD.Period}\n"); dat.AppendFormat($"\t Phase={FFBPacket.FFB_EFF_PERIOD.Phase}"); logger.Trace(dat); } break; case FFBPType.PT_CONSTREP: // Constant Force Report if (joystick.Ffb_h_Eff_Constant(data, ref FFBPacket.FFB_EFF_CONSTANT) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_CONSTANT.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Constant Force Report, magnitude={FFBPacket.FFB_EFF_CONSTANT.Magnitude}"); } break; case FFBPType.PT_RAMPREP: // Ramp Force Report if (joystick.Ffb_h_Eff_Ramp(data, ref FFBPacket.FFB_EFF_RAMP) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_RAMP.EffectBlockIndex; logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Ramp Force Report"); StringBuilder dat = new StringBuilder(); dat.AppendFormat($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Ramp Force Report\n"); dat.AppendFormat($"\t EBI={FFBPacket.FFB_EFF_RAMP.EffectBlockIndex}\n"); dat.AppendFormat($"\t Start={FFBPacket.FFB_EFF_RAMP.Start}\n"); dat.AppendFormat($"\t End={FFBPacket.FFB_EFF_RAMP.End}\n"); logger.Trace(dat); } break; case FFBPType.PT_CSTMREP: // Custom Force Data Report logger.Debug($"Custom Force Data Report"); break; case FFBPType.PT_SMPLREP: // Download Force Sample joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Download Force Sample"); break; case FFBPType.PT_EFOPREP: // Effect Operation Report if (joystick.Ffb_h_EffOp(data, ref FFBPacket.FFB_EFF_OP) == ERROR_SUCCESS) { FFBPacket.BlockIndex = (uint)FFBPacket.FFB_EFF_OP.EffectBlockIndex; logger.Trace($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Effect Operation Report loop={FFBPacket.FFB_EFF_OP.LoopCount} action={FFBPacket.FFB_EFF_OP.EffectOp}"); } break; case FFBPType.PT_BLKFRREP: // PID Block Free Report joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] PID Block Free Report"); break; case FFBPType.PT_CTRLREP: // PID Device Control joystick.Ffb_h_DevCtrl(data, ref FFBPacket.FFB_CTRL); logger.Debug($"[{FFBPacket.ID}][_] PID Device Control {FFBPacket.FFB_CTRL}"); break; case FFBPType.PT_GAINREP: // Device Gain Report joystick.Ffb_h_DevGain(data, ref FFBPacket.Gain); logger.Debug($"[{FFBPacket.ID}][_] Device Gain Report={FFBPacket.Gain}"); break; case FFBPType.PT_SETCREP: // Set Custom Force Report joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Set Custom Force Report"); break; case FFBPType.PT_NEWEFREP: // Create New Effect Report !! joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); joystick.Ffb_h_CreateNewEffect(data, ref FFBPacket.FFBENextType, ref FFBPacket.NextBlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Create New Effect Report, next={FFBPacket.FFBENextType}[nextEBI={FFBPacket.NextBlockIndex}]"); break; case FFBPType.PT_BLKLDREP: // Block Load Report joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] Block Load Report"); break; case FFBPType.PT_POOLREP: // PID Pool Report joystick.Ffb_h_EBI(data, ref FFBPacket.BlockIndex); logger.Debug($"[{FFBPacket.ID}][EBI={FFBPacket.BlockIndex}] PID Pool Report"); break; } // FFBDataReceived?.Invoke(FFBPacket); return(FFBPacket); } return(null); }
public void InitFromFFBPacket(VirtualFFBPacket packet) { if (packet._FFBPType != FFBPType.PT_NEWEFREP && packet._FFBPType != FFBPType.PT_EFFREP) { return; } if (this.Parameters.Index == 10000) { FFBEType type; if (packet._FFBPType == FFBPType.PT_NEWEFREP) { type = packet.FFBENextType; } else { type = packet.FFB_EFF_REPORT.EffectType; } this.Parameters.Type = VirtualController.virtualEffectGuidMap[type]; this.Parameters.Index = packet.BlockIndex; switch (type) { case FFBEType.ET_CONST: { if (this.Parameters.Parameters == null) { this.Parameters.Parameters = new ConstantForce() { Magnitude = 10000, } } ; this.Parameters.FType = ForceType.Constant; break; } case FFBEType.ET_RAMP: { if (this.Parameters.Parameters == null) { this.Parameters.Parameters = new RampForce() { Start = -10000, End = 10000, } } ; this.Parameters.FType = ForceType.Ramp; break; } case FFBEType.ET_SINE: case FFBEType.ET_SQR: case FFBEType.ET_STDN: case FFBEType.ET_STUP: case FFBEType.ET_TRNGL: { if (this.Parameters.Parameters == null) { this.Parameters.Parameters = new PeriodicForce() { Magnitude = 10000, Offset = 0, Period = 500000, Phase = 0 } } ; this.Parameters.FType = ForceType.Periodic; break; } case FFBEType.ET_DMPR: case FFBEType.ET_FRCTN: case FFBEType.ET_INRT: case FFBEType.ET_SPRNG: { if (this.Parameters.Parameters == null) { this.Parameters.Parameters = new ConditionSet(); this.Parameters.Parameters.As <ConditionSet>().Conditions = new Condition[1]; this.Parameters.Parameters.As <ConditionSet>().Conditions[0] = new Condition() { DeadBand = 0, NegativeCoefficient = 10000, NegativeSaturation = 10000, Offset = 0, PositiveCoefficient = 10000, PositiveSaturation = 10000 }; } this.Parameters.FType = ForceType.Condition; break; } case FFBEType.ET_CSTM: { break; } } Parameters.Duration = -1; Parameters.Gain = 10000; Parameters.SamplePeriod = 0; Parameters.StartDelay = 0; Parameters.TriggerButton = -1; Parameters.TriggerRepeatInterval = 0; Parameters.Flags = (EffectFlags.ObjectIds | EffectFlags.Cartesian); Parameters.Directions = new int[1] { 1 }; } }
public void UpdateFromFFBPacket(VirtualFFBPacket packet) { if (packet._FFBPType != FFBPType.PT_EFFREP) { return; } if (packet.FFB_EFF_REPORT.Duration == 65535) { Parameters.Duration = -1; } else { Parameters.Duration = (int)(packet.FFB_EFF_REPORT.Duration * 1000); } Parameters.Gain = (int)(packet.FFB_EFF_REPORT.Gain * (10000 / 255.0)); Parameters.SamplePeriod = (int)(packet.FFB_EFF_REPORT.SamplePrd * 1000); Parameters.StartDelay = 0; if (packet.FFB_EFF_REPORT.TrigerBtn == 255) { Parameters.TriggerButton = -1; } else { Parameters.TriggerButton = (int)packet.FFB_EFF_REPORT.TrigerBtn; } Parameters.TriggerRepeatInterval = (int)(packet.FFB_EFF_REPORT.TrigerRpt * 1000); Parameters.Flags = (EffectFlags.ObjectIds | EffectFlags.Cartesian); /* * So there a very strange moment: vjoy always sends packet.FFB_EFF_REPORT.Polar is true. * So, a solution also very strange and hacky. */ if (packet.FFB_EFF_REPORT.Polar) { Parameters.Directions = new int[1]; // 1/0 + 0 = 8191 // -1 + 0 = 24575 // 0 + 1 = 16383 // 0 +-1 = 0 // switch (packet.FFB_EFF_REPORT.Direction) { case 0: { Program.logger.Fatal($"RECIVED ZERO PACKET _START"); Program.logger.Fatal(packet.GenerateEffectInfo()); Program.logger.Fatal($"RECIVED ZERO PACKET _END"); Parameters.Directions[0] = 0; break; } case 8191: { Parameters.Directions[0] = 1; break; } case 24575: { Parameters.Directions[0] = -1; break; } default: { Parameters.Directions[0] = 0; break; } } } else { Parameters.Directions = new int[2]; Parameters.Directions[0] = (int)packet.FFB_EFF_REPORT.DirX; Parameters.Directions[1] = (int)packet.FFB_EFF_REPORT.DirY; Program.logger.Fatal($"RECIVED NOT POLAR PACKET _START"); Program.logger.Fatal(packet.GenerateEffectInfo()); Program.logger.Fatal($"RECIVED NOT POLAR PACKET _END"); } //effectParameters.AxisSettings = new AxisSettings(2); //Parameters.Directions = new int[2]; /*int num = 0; * int num2 = 0; * if (packet.FFB_EFF_REPORT.Polar) { * Utils.GetDICartesianXY((int)packet.FFB_EFF_REPORT.DirX, ref num, ref num2); * } else { * num = (int)packet.FFB_EFF_REPORT.DirX; * num2 = (int)packet.FFB_EFF_REPORT.DirY; * } * Parameters.Directions[0] = num; * Parameters.Directions[1] = num2; */ }