Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
00fox authored Dec 10, 2021
1 parent bd752f9 commit 5ab800b
Show file tree
Hide file tree
Showing 84 changed files with 40,280 additions and 0 deletions.
319 changes: 319 additions & 0 deletions Ds2vJoy/CEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
#include "stdafx.h"
#include "CEffect.h"

//----------------------------------------------------------------------------------------------
// Transplant
// Force Feedback Driver for XInput
//----------------------------------------------------------------------------------------------

CEffect::CEffect()
:m_Type(FFBEType::ET_NONE)
{
// status
m_Status = 0;
// View
m_PlayCount = 0;
// Rebirth moment
m_StartTime = 0;
}

//----------------------------------------------------------------------------------------------
// Calc
//----------------------------------------------------------------------------------------------

BOOL CEffect::Calc(
long* LeftLevel
, long* RightLevel
, double CurrentTime)
{
if (m_Status == FALSE)
return FALSE;

// Calculate the playback time, start time, end time, and current time of the effect
unsigned long Duration = max(1, m_report.Duration);
double EndTime = DBL_MAX;
if (m_PlayCount != -1 && Duration != 0xFFFF)
{
EndTime = m_StartTime + (double)Duration * m_PlayCount;
}

// Is the effect playing?
if (CurrentTime <= EndTime)
{

// Calculate the envelope
long NormalRate;
long AttackLevel;
long FadeLevel;
CalcEnvelope(
Duration
, static_cast<ULONG>(CurrentTime - m_StartTime) % Duration
, &NormalRate
, &AttackLevel
, &FadeLevel);

// Calculate the force
long NormalLevel;
long WorkLeftLevel;
long WorkRightLevel;
CalcForce(
Duration
, static_cast<ULONG>(CurrentTime - m_StartTime) % Duration
, NormalRate
, AttackLevel
, FadeLevel
, &NormalLevel);

// Adjust the positive and negative of the force
WorkLeftLevel = (NormalLevel > 0) ? NormalLevel : -NormalLevel;
WorkRightLevel = (NormalLevel > 0) ? NormalLevel : -NormalLevel;

// Adjust the force cap
WorkLeftLevel = min(0xFF, WorkLeftLevel * 0xFF / 10000);
WorkRightLevel = min(0xFF, WorkRightLevel * 0xFF / 10000);

// Add force
*LeftLevel = *LeftLevel + WorkLeftLevel;
*RightLevel = *RightLevel + WorkRightLevel;
return TRUE;
}
m_Status = FALSE;
return FALSE;
}

//----------------------------------------------------------------------------------------------
// CalcEnvelope
//----------------------------------------------------------------------------------------------

VOID CEffect::CalcEnvelope(
unsigned long Duration
, unsigned long CurrentPos
, long* NormalRate
, long* AttackLevel
, long* FadeLevel)
{
// Calculate the envelope
if (m_bEnbelope)
{
// Calculate the rate of attack
long AttackRate = 0;
unsigned long AttackTime = max(1, m_envelope.AttackTime);
if (CurrentPos < AttackTime)
{
AttackRate = (AttackTime - CurrentPos) * 100 / AttackTime;
}

// Calculate the percentage of fades
long FadeRate = 0;
unsigned long FadeTime = max(1, m_envelope.FadeTime);
unsigned long FadePos = Duration - FadeTime;
if (FadePos < CurrentPos)
{
FadeRate = (CurrentPos - FadePos) * 100 / FadeTime;
}

// Returns the calculated value
*NormalRate = 100 - AttackRate - FadeRate;
*AttackLevel = m_envelope.AttackLevel * AttackRate;
*FadeLevel = m_envelope.FadeLevel * FadeRate;

}
else
{

*NormalRate = 100;
*AttackLevel = 0;
*FadeLevel = 0;
}
}

//----------------------------------------------------------------------------------------------
// CalcForce
//----------------------------------------------------------------------------------------------

VOID CEffect::CalcForce(
unsigned long Duration
, unsigned long CurrentPos
, long NormalRate
, long AttackLevel
, long FadeLevel
, long* NormalLevel)
{
long Magnitude = 0;
long Period;
long R;
long Rate;

FFBEType type = m_Type == FFBEType::ET_NONE ? m_report.EffectType : m_Type;

// Sort processing according to the type of effect
switch (type)
{
case ET_SPRNG:
case ET_DMPR:
case ET_INRT:
case ET_FRCTN:
;
break;

// Constant force
case ET_CONST:
// Find the magnitude considering the envelope
Magnitude = m_constantForce.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;
break;

// Custom force
case ET_CSTM:
;
break;

// Periodic effect
case ET_SQR:

// Find somewhere between 0 and 359 degrees from the time (milliseconds) and elapsed time of one cycle.
Period = max(1, m_periodic.Period);
R = (CurrentPos % Period) * 360 / Period;

// Calculate the phase
R = (R + (m_periodic.Phase / 100)) % 360;

// Find the magnitude considering the envelope
Magnitude = m_periodic.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;

// Find the magnitude considering the square
if (180 <= R)
{
Magnitude = Magnitude * -1;
}

// Calculate the offset
Magnitude = Magnitude + m_periodic.Offset;
break;

case ET_SINE:

// Find somewhere between 0 and 359 degrees from the time (milliseconds) and elapsed time of one cycle.
Period = max(1, m_periodic.Period);
R = (CurrentPos % Period) * 360 / Period;

// Calculate the phase
R = (R + (m_periodic.Phase / 100)) % 360;

// Find the magnitude considering the envelope
Magnitude = m_periodic.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;

// Find the magnitude considering the square
Magnitude = static_cast<LONG>(Magnitude * sin(R * 3.1415 / 180.0));

// Calculate the offset
Magnitude = Magnitude + m_periodic.Offset;
break;

case ET_TRNGL:

// Find somewhere between 0 and 359 degrees from the time (milliseconds) and elapsed time of one cycle.
Period = max(1, m_periodic.Period);
R = (CurrentPos % Period) * 360 / Period;

// Calculate the phase
R = (R + (m_periodic.Phase / 100)) % 360;

// Find the magnitude considering the envelope
Magnitude = m_periodic.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;

// Find the magnitude considering the triangular wave
if (0 <= R && R < 90)
{
Magnitude = -Magnitude * (90 - R) / 90;
}
if (90 <= R && R < 180)
{
Magnitude = Magnitude * (R - 90) / 90;
}
if (180 <= R && R < 270)
{
Magnitude = Magnitude * (90 - (R - 180)) / 90;
}
if (270 <= R && R < 360)
{
Magnitude = -Magnitude * (R - 270) / 90;
}
// Calculate the offset
Magnitude = Magnitude + m_periodic.Offset;
break;

case ET_STUP:

// Find somewhere between 0 and 359 degrees from the time (milliseconds) and elapsed time of one cycle.
Period = max(1, m_periodic.Period);
R = (CurrentPos % Period) * 360 / Period;

// Calculate the phase
R = (R + (m_periodic.Phase / 100)) % 360;

// Find the magnitude considering the envelope
Magnitude = m_periodic.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;

// Finding a magnitude that takes up saw teeth into consideration
if (0 <= R && R < 180)
{
Magnitude = -Magnitude * (180 - R) / 180;
}
if (180 <= R && R < 360)
{
Magnitude = Magnitude * (R - 180) / 180;
}

// Calculate the offset
Magnitude = Magnitude + m_periodic.Offset;
break;

case ET_STDN:

// Find somewhere between 0 and 359 degrees from the time (milliseconds) and elapsed time of one cycle.
Period = max(1, m_periodic.Period);
R = (CurrentPos % Period) * 360 / Period;

// Calculate the phase
R = (R + (m_periodic.Phase / 100)) % 360;

// Find the magnitude considering the envelope
Magnitude = m_periodic.Magnitude;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;

// Finding a magnitude that takes down feathers into consideration
if (0 <= R && R < 180)
{
Magnitude = Magnitude * (180 - R) / 180;
}
if (180 <= R && R < 360)
{
Magnitude = -Magnitude * (R - 180) / 180;
}

// Calculate the offset
Magnitude = Magnitude + m_periodic.Offset;
break;

// Inclined force
case ET_RAMP:

// Calculate the ratio of start point and end point
Rate = (Duration - CurrentPos) * 100
/ max(1, m_report.Duration);

// Find the magnitude considering the envelope
Magnitude = (m_rampForce.Start * Rate
+ m_rampForce.End * (100 - Rate)) / 100;
Magnitude = (Magnitude * NormalRate + AttackLevel + FadeLevel) / 100;
break;
}

// Returns a force that takes gain into account
*NormalLevel = Magnitude * m_report.Gain / 0xFF;
}
49 changes: 49 additions & 0 deletions Ds2vJoy/CEffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

//----------------------------------------------------------------------------------------------
// Transplant
// Force Feedback Driver for XInput
//----------------------------------------------------------------------------------------------

class CEffect
{
public:
// Constructor
CEffect();

// Calculate the effect
BOOL Calc(LONG*, LONG*, double CurrentTime);

// Type
FFBEType m_Type;
// DIEFFECT
FFB_EFF_REPORT m_report = { 0 };

// DIENVELOPE
FFB_EFF_ENVLP m_envelope = { 0 };
bool m_bEnbelope;

// DICONSTANTFORCE
FFB_EFF_CONSTANT m_constantForce = { 0 };

// DIPERIODIC
FFB_EFF_PERIOD m_periodic = { 0 };

// DIRAMPFORCE
FFB_EFF_RAMP m_rampForce = { 0 };

// status
DWORD m_Status;
// View
unsigned long m_PlayCount;
// Rebirth moment
double m_StartTime;

private:
// Calculate the envelope
VOID CalcEnvelope(ULONG, ULONG, LONG*, LONG*, LONG*);
// Calculate the force
VOID CalcForce(ULONG, ULONG, LONG, LONG, LONG, LONG*);

protected:
};
Loading

0 comments on commit 5ab800b

Please sign in to comment.