Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  accel
Language: C/C++
Code:
#include "interception.h"
#include "utils.h"
#include <windows.h>
#include <math.h>
#include <iostream>
#include <string>
#include <chrono>

//MorinTedronai Coding Solutions Inc. 2020 - v1.0 "Better dead then red"

void setDirectionVars(double& prev, std::chrono::time_point<std::chrono::high_resolution_clock>& prevTime, int direction, double distance, double& deltaDistance) {
     if (prev != direction) {
          prevTime = std::chrono::high_resolution_clock::now();
          deltaDistance = 0;
     }
     else {
          deltaDistance += std::abs(distance);
     }
     prev = direction;
}

double getMult(double spectrum, double power, double delta, double to1K) {
     //wrong
     //return (spectrum * to1K - pow((pow(spectrum * to1K, power) - pow((spectrum - delta) * to1K, power)), 1 / power)) / 1000;
     //right
       return pow(spectrum - delta, power);
}

int main()
{
     InterceptionContext context;
     InterceptionDevice device;
     InterceptionStroke stroke;

     raise_process_priority();
     context = interception_create_context();
     interception_set_filter(context, interception_is_mouse, INTERCEPTION_FILTER_MOUSE_MOVE);

     double
          dx,
          dy,
          power,
          tempMultX = 0,
          tempMultY = 0,
          remainderX = 0,
          remainderY = 0,
          var_durationSens = 1,
          var_distanceSens = 1,
          var_duration = 333, // in ms
          var_distance = 200,
          var_power = 1.5,
          var_postScaleX = 1,
          var_postScaleY = 1,
          var_angleSnap = 0,
          pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406,
          hypot,
          angle,
          newangle,
          deltaTimeYms,
          deltaDistanceY,
          variableValue,
          var_deadzone = 3,
          var_distanceBased = 1,
          var_durationBased = 0,
          prevYDirection = 0,
          prevXDirection = 0,
          posYCounter = 0,
          negYCounter = 0;

     auto prevYDirectionTime = std::chrono::high_resolution_clock::now();
     auto prevXDirectionTime = std::chrono::high_resolution_clock::now();
     auto currentTime = std::chrono::high_resolution_clock::now();
     std::chrono::duration<double> deltaTimeY;
     std::chrono::duration<double> deltaTimeX;
     char variableName[24];

     HANDLE hConsole;
     hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

     CONSOLE_FONT_INFOEX cfi;
     cfi.cbSize = sizeof cfi;
     cfi.nFont = 0;
     cfi.dwFontSize.X = 0;
     cfi.dwFontSize.Y = 14;
     cfi.FontFamily = FF_DONTCARE;
     cfi.FontWeight = FW_NORMAL;
     SetCurrentConsoleFontEx(hConsole, FALSE, &cfi);

     SetConsoleTextAttribute(hConsole, 0x0f);
     printf("ESF-Decelerator v0.2.0n=============================================nn");
     SetConsoleTextAttribute(hConsole, 0x08);


     printf("Reading config from settings.txt...n");

     FILE* fp;

     if ((fp = fopen("settings.txt", "r+")) == NULL) {
          SetConsoleTextAttribute(hConsole, 0x04);
          printf("* Cannot read from settings.txt - Using defaults.n");
          SetConsoleTextAttribute(hConsole, 0x08);
     }
     else
     {
          for (int i = 0; i < 50 && fscanf(fp, "%s = %lf", &variableName, &variableValue) != EOF; i++) {
               if (strcmp(variableName, "DistanceSensitivity") == 0)
               {
                    var_distanceSens = variableValue;
               }
               if (strcmp(variableName, "DurationSensitivity") == 0)
               {
                    var_durationSens = variableValue;
               }
               else if (strcmp(variableName, "Duration") == 0)
               {
                    var_duration = variableValue;
               }
               else if (strcmp(variableName, "Distance") == 0)
               {
                    var_distance = variableValue;
               }
               else if (strcmp(variableName, "Deadzone") == 0)
               {
                    var_deadzone = variableValue;
               }
               else if (strcmp(variableName, "Power") == 0)
               {
                    var_power = variableValue;
               }
               else if (strcmp(variableName, "Post-ScaleX") == 0)
               {
                    var_postScaleX = variableValue;
               }
               else if (strcmp(variableName, "Post-ScaleY") == 0)
               {
                    var_postScaleY = variableValue;
               }
               else if (strcmp(variableName, "AngleSnapping") == 0)
               {
                    var_angleSnap = variableValue;
               }
               else if (strcmp(variableName, "DistanceBased") == 0)
               {
                    var_durationBased = variableValue;
               }
               else if (strcmp(variableName, "DurationBased") == 0)
               {
                    var_durationBased = variableValue;
               }
          }
          fclose(fp);
     }

     SetConsoleTextAttribute(hConsole, 0x02);
     printf("Distance-based enabled: %fnDuration-based enabled: %fnnDistance Sensitivity: %fnDuration Sensitivity: %fnDistance: %fnDuration: %fnDeadzone: %fnPower: %fnPost-Scale: x: %f, y: %fnAngle Snapping: %fnn", var_distanceBased, var_durationBased, var_distanceSens, var_durationSens, var_distance, var_duration, var_deadzone, var_power, var_postScaleX, var_postScaleY, var_angleSnap);
     SetConsoleTextAttribute(hConsole, 0x08);

     printf("CTRL + C to close");

     double to1Kduration = 1000 / var_duration; // so we get smooth 0-100% multipliers in the acceleration
     double to1Kdistance = 1000 / var_distance;

     while (interception_receive(context, device = interception_wait(context), &stroke, 1) > 0)
     {

          if (interception_is_mouse(device))
          {
               InterceptionMouseStroke& mstroke = *(InterceptionMouseStroke*)&stroke;

               if (!(mstroke.flags & INTERCEPTION_MOUSE_MOVE_ABSOLUTE)) {

                    // retrieve new mouse data
                    dx = (double)mstroke.x;
                    dy = (double)mstroke.y;

                    // Figure out mouse direction changes
                    if (dy < 0) {
                         posYCounter = 0;
                         negYCounter++;
                         if (negYCounter > var_deadzone) {
                              setDirectionVars(prevYDirection, prevYDirectionTime, 1, dy, deltaDistanceY);
                         }
                    }
                    else if (dy > 0) {
                         negYCounter = 0;
                         posYCounter++;
                         if (posYCounter > var_deadzone) {
                              setDirectionVars(prevYDirection, prevYDirectionTime, 2, dy, deltaDistanceY);
                         }
                    }

                    // update acceleration timers
                    currentTime = std::chrono::high_resolution_clock::now();
                    deltaTimeY = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - prevYDirectionTime);
                    deltaTimeYms = deltaTimeY.count() * 1000;

                    // angle snapping
                    // credit: Povohat
                    // thought it may be interesting to experiment with this.
                    if (var_angleSnap && deltaTimeYms <= var_duration) {
                         hypot = sqrt(dx * dx + dy * dy); // convert to polar
                         newangle = angle = atan2(dy, dx);


                         if (fabs(cos(angle)) < (var_angleSnap * pi / 180)) {     // test for vertical
                              if (sin(angle) > 0) {
                                   newangle = pi / 2;
                              }
                              else {
                                   newangle = 3 * pi / 2;
                              }
                         }
                         else
                              if (fabs(sin(angle)) < (var_angleSnap * pi / 180)) {     // test for horizontal
                                   if (cos(angle) < 0) {
                                        newangle = pi;
                                   }
                                   else {
                                        newangle = 0;
                                   }
                              }

                         dx = hypot * cos(newangle); // convert back to cartesian
                         dy = hypot * sin(newangle);
                    }

                    // apply time-based acceleration or distance-based acceleration
                    if (var_durationBased && deltaTimeYms <= var_duration) {
                         tempMultY = getMult(var_duration, var_power, deltaTimeYms, to1Kduration);
                         dy *= 1 + var_durationSens * tempMultY;
                    }
                    else if (var_distanceBased && deltaDistanceY <= var_distance) {
                         tempMultY = getMult(var_distance, var_power, deltaDistanceY, to1Kdistance);     
                         dy *= 1 + var_distanceSens * tempMultY;
                    }
                    else {
                         tempMultY = 0;
                    }

                    // apply post-scale
                    dx *= var_postScaleX;
                    dy *= var_postScaleY;

                    // add remainder from last input
                    dx += remainderX;
                    dy += remainderY;

                    // remainder gets passed into next cycle
                    remainderX = dx - floor(dx);
                    remainderY = dy - floor(dy);

                    // output new counts
                    mstroke.x = (int)floor(dx);
                    mstroke.y = (int)floor(dy);
               }

               interception_send(context, device, &stroke, 1);
          }
     }

     interception_destroy_context(context);

     return 0;
}
          
Comments: