Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autofire capability #77

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Windows/Gopher/ConfigFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ void ConfigFile::ExtractKeys()
outfile << "GAMEPAD_TRIGGER_LEFT = 0" << std::endl;
outfile << "GAMEPAD_TRIGGER_RIGHT = 0" << std::endl;
outfile << "\n" << std::endl;
outfile << "# SET TO 1 FOR EACH CONTROLLER BUTTON (AS NAMED ABOVE) TO HAVE Gopher360 CONTINUALLY PULSE THE KEY WHILST IT IS HELD DOWN (I.E. AUTOFIRE)" << std::endl;
outfile << "GAMEPAD_DPAD_UP_REPEAT = 1" << std::endl;
outfile << "GAMEPAD_DPAD_DOWN_REPEAT = 1" << std::endl;
outfile << "GAMEPAD_DPAD_LEFT_REPEAT = 1" << std::endl;
outfile << "GAMEPAD_DPAD_RIGHT_REPEAT = 1" << std::endl;
outfile << "\n" << std::endl;
outfile << "# ALLOWED CURSOR SPEEDS, FIRST WILL BE CHOSEN BY DEFAULT. VALUES > 1.0 WILL BE IGNORED. NO SPACES." << std::endl;
outfile << "CURSOR_SPEED = ULTRALOW=0.005,LOW=0.015,MED=0.025,HIGH=0.04" << std::endl;
outfile << "# SET ACCELERATION FACTOR FOR NON-LINEAR CURSOR SPEED" << std::endl;
Expand Down
102 changes: 84 additions & 18 deletions Windows/Gopher/Gopher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ void Gopher::loadConfigFile()
GAMEPAD_TRIGGER_LEFT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_TRIGGER_LEFT").c_str(), 0, 0);
GAMEPAD_TRIGGER_RIGHT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_TRIGGER_RIGHT").c_str(), 0, 0);

//Whether to enable the automatic repeat (autofire) functionality for each button
GAMEPAD_DPAD_UP_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_DPAD_UP_REPEAT").c_str(), 0, 0);
GAMEPAD_DPAD_DOWN_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_DPAD_DOWN_REPEAT").c_str(), 0, 0);
GAMEPAD_DPAD_LEFT_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_DPAD_LEFT_REPEAT").c_str(), 0, 0);
GAMEPAD_DPAD_RIGHT_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_DPAD_RIGHT_REPEAT").c_str(), 0, 0);
GAMEPAD_START_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_START_REPEAT").c_str(), 0, 0);
GAMEPAD_BACK_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_BACK_REPEAT").c_str(), 0, 0);
GAMEPAD_LEFT_THUMB_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_LEFT_THUMB_REPEAT").c_str(), 0, 0);
GAMEPAD_RIGHT_THUMB_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_RIGHT_THUMB_REPEAT").c_str(), 0, 0);
GAMEPAD_LEFT_SHOULDER_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_LEFT_SHOULDER_REPEAT").c_str(), 0, 0);
GAMEPAD_RIGHT_SHOULDER_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_RIGHT_SHOULDER_REPEAT").c_str(), 0, 0);
GAMEPAD_A_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_A_REPEAT").c_str(), 0, 0);
GAMEPAD_B_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_B_REPEAT").c_str(), 0, 0);
GAMEPAD_X_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_X_REPEAT").c_str(), 0, 0);
GAMEPAD_Y_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_Y_REPEAT").c_str(), 0, 0);
GAMEPAD_TRIGGER_LEFT_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_TRIGGER_LEFT_REPEAT").c_str(), 0, 0);
GAMEPAD_TRIGGER_RIGHT_REPEAT = strtol(cfg.getValueOfKey<std::string>("GAMEPAD_TRIGGER_RIGHT_REPEAT").c_str(), 0, 0);

// Acceleration factor
acceleration_factor = strtof(cfg.getValueOfKey<std::string>("ACCELERATION_FACTOR").c_str(), 0);

Expand Down Expand Up @@ -175,33 +193,33 @@ void Gopher::loop() {
//Set all controller keys.
handleTriggers(GAMEPAD_TRIGGER_LEFT, GAMEPAD_TRIGGER_RIGHT);
if (GAMEPAD_DPAD_UP)
mapKeyboard(XINPUT_GAMEPAD_DPAD_UP, GAMEPAD_DPAD_UP);
mapKeyboard(XINPUT_GAMEPAD_DPAD_UP, GAMEPAD_DPAD_UP, GAMEPAD_DPAD_UP_REPEAT);
if (GAMEPAD_DPAD_DOWN)
mapKeyboard(XINPUT_GAMEPAD_DPAD_DOWN, GAMEPAD_DPAD_DOWN);
mapKeyboard(XINPUT_GAMEPAD_DPAD_DOWN, GAMEPAD_DPAD_DOWN, GAMEPAD_DPAD_DOWN_REPEAT);
if (GAMEPAD_DPAD_LEFT)
mapKeyboard(XINPUT_GAMEPAD_DPAD_LEFT, GAMEPAD_DPAD_LEFT);
mapKeyboard(XINPUT_GAMEPAD_DPAD_LEFT, GAMEPAD_DPAD_LEFT, GAMEPAD_DPAD_LEFT_REPEAT);
if (GAMEPAD_DPAD_RIGHT)
mapKeyboard(XINPUT_GAMEPAD_DPAD_RIGHT, GAMEPAD_DPAD_RIGHT);
mapKeyboard(XINPUT_GAMEPAD_DPAD_RIGHT, GAMEPAD_DPAD_RIGHT, GAMEPAD_DPAD_RIGHT_REPEAT);
if (GAMEPAD_START)
mapKeyboard(XINPUT_GAMEPAD_START, GAMEPAD_START);
mapKeyboard(XINPUT_GAMEPAD_START, GAMEPAD_START, GAMEPAD_START_REPEAT);
if (GAMEPAD_BACK)
mapKeyboard(XINPUT_GAMEPAD_BACK, GAMEPAD_BACK);
mapKeyboard(XINPUT_GAMEPAD_BACK, GAMEPAD_BACK, GAMEPAD_BACK_REPEAT);
if (GAMEPAD_LEFT_THUMB)
mapKeyboard(XINPUT_GAMEPAD_LEFT_THUMB, GAMEPAD_LEFT_THUMB);
mapKeyboard(XINPUT_GAMEPAD_LEFT_THUMB, GAMEPAD_LEFT_THUMB, GAMEPAD_LEFT_THUMB_REPEAT);
if (GAMEPAD_RIGHT_THUMB)
mapKeyboard(XINPUT_GAMEPAD_RIGHT_THUMB, GAMEPAD_RIGHT_THUMB);
mapKeyboard(XINPUT_GAMEPAD_RIGHT_THUMB, GAMEPAD_RIGHT_THUMB, GAMEPAD_RIGHT_THUMB_REPEAT);
if (GAMEPAD_LEFT_SHOULDER)
mapKeyboard(XINPUT_GAMEPAD_LEFT_SHOULDER, GAMEPAD_LEFT_SHOULDER);
mapKeyboard(XINPUT_GAMEPAD_LEFT_SHOULDER, GAMEPAD_LEFT_SHOULDER, GAMEPAD_LEFT_SHOULDER_REPEAT);
if (GAMEPAD_RIGHT_SHOULDER)
mapKeyboard(XINPUT_GAMEPAD_RIGHT_SHOULDER, GAMEPAD_RIGHT_SHOULDER);
mapKeyboard(XINPUT_GAMEPAD_RIGHT_SHOULDER, GAMEPAD_RIGHT_SHOULDER, GAMEPAD_RIGHT_SHOULDER_REPEAT);
if (GAMEPAD_A)
mapKeyboard(XINPUT_GAMEPAD_A, GAMEPAD_A);
mapKeyboard(XINPUT_GAMEPAD_A, GAMEPAD_A, GAMEPAD_A_REPEAT);
if (GAMEPAD_B)
mapKeyboard(XINPUT_GAMEPAD_B, GAMEPAD_B);
mapKeyboard(XINPUT_GAMEPAD_B, GAMEPAD_B, GAMEPAD_B_REPEAT);
if (GAMEPAD_X)
mapKeyboard(XINPUT_GAMEPAD_X, GAMEPAD_X);
mapKeyboard(XINPUT_GAMEPAD_X, GAMEPAD_X, GAMEPAD_X_REPEAT);
if (GAMEPAD_Y)
mapKeyboard(XINPUT_GAMEPAD_Y, GAMEPAD_Y);
mapKeyboard(XINPUT_GAMEPAD_Y, GAMEPAD_Y, GAMEPAD_Y_REPEAT);
}

void Gopher::pulseVibrate(const int duration, const int l, const int r) const
Expand Down Expand Up @@ -343,10 +361,27 @@ void Gopher::handleTriggers(WORD lKey, WORD rKey)
if (lTriggerIsDown)
{
inputKeyboardDown(lKey);
_lTriggerLongPressCount = 0;
}
else
{
inputKeyboardUp(lKey);
_lTriggerLongPressMax = 500; // reset long press max trigger
}
}
else if (GAMEPAD_TRIGGER_LEFT_REPEAT && lTriggerIsDown)
{
_lTriggerLongPressCount++;
if (_lTriggerLongPressCount * SLEEP_AMOUNT > _lTriggerLongPressMax)
{
// pulse the key
inputKeyboardUp(lKey);
inputKeyboardDown(lKey);
_lTriggerLongPressCount = 0;
if (_lTriggerLongPressMax == 500)
_lTriggerLongPressMax = 200;
else
_lTriggerLongPressMax = 70;
}
}

Expand All @@ -360,6 +395,22 @@ void Gopher::handleTriggers(WORD lKey, WORD rKey)
else
{
inputKeyboardUp(rKey);
_rTriggerLongPressMax = 500;
}
}
else if (GAMEPAD_TRIGGER_RIGHT_REPEAT && rTriggerIsDown)
{
_rTriggerLongPressCount++;
if (_rTriggerLongPressCount * SLEEP_AMOUNT > _rTriggerLongPressMax)
{
// pulse the key
inputKeyboardUp(rKey);
inputKeyboardDown(rKey);
_rTriggerLongPressCount = 0;
if (_rTriggerLongPressMax == 500)
_rTriggerLongPressMax = 200;
else
_rTriggerLongPressMax = 70;
}
}
}
Expand All @@ -368,6 +419,7 @@ void Gopher::setXboxClickState(DWORD STATE)
{
_xboxClickIsDown[STATE] = false;
_xboxClickIsUp[STATE] = false;
_xboxClickIsDownLong[STATE] = false;

if (!this->xboxClickStateExists(STATE))
{
Expand All @@ -381,21 +433,28 @@ void Gopher::setXboxClickState(DWORD STATE)
_xboxClickStateLastIteration[STATE] = true;
_xboxClickIsDown[STATE] = true;
_xboxClickDownLength[STATE] = 0;
_xboxClickIsDownLong[STATE] = false;
_xboxClickDownLongMax[STATE] = 500;
}

if (isDown && _xboxClickStateLastIteration[STATE])
{
// _xboxClickDownLong toggles every 200 ms of button depression
_xboxClickDownLength[STATE] = _xboxClickDownLength[STATE] + 1;
if (_xboxClickDownLength[STATE] * SLEEP_AMOUNT > 200)
if (_xboxClickDownLength[STATE] * SLEEP_AMOUNT > _xboxClickDownLongMax[STATE])
{
_xboxClickIsDownLong[STATE] = true;
_xboxClickDownLength[STATE] = 0;
if (_xboxClickDownLongMax[STATE] == 500)
_xboxClickDownLongMax[STATE] = 200;
else
_xboxClickDownLongMax[STATE] = 70;
}
}

if (!isDown && _xboxClickStateLastIteration[STATE])
{
_xboxClickStateLastIteration[STATE] = false;
_xboxClickIsUp[STATE] = true;
_xboxClickIsDownLong[STATE] = false;
}

_xboxClickStateLastIteration[STATE] = isDown;
Expand All @@ -412,7 +471,7 @@ bool Gopher::xboxClickStateExists(DWORD xinput)
return true;
}

void Gopher::mapKeyboard(DWORD STATE, WORD key)
void Gopher::mapKeyboard(DWORD STATE, WORD key, int repeat)
{
setXboxClickState(STATE);
if (_xboxClickIsDown[STATE])
Expand All @@ -424,6 +483,13 @@ void Gopher::mapKeyboard(DWORD STATE, WORD key)
{
inputKeyboardUp(key);
}

if (repeat && _xboxClickIsDownLong[STATE])
{
// pulse key off and on
inputKeyboardUp(key);
inputKeyboardDown(key);
}
}

void Gopher::mapMouseClick(DWORD STATE, DWORD keyDown, DWORD keyUp)
Expand Down
24 changes: 23 additions & 1 deletion Windows/Gopher/Gopher.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Gopher
bool _hidden = false; //press Y to hide, check this var
bool _lTriggerPrevious = false;
bool _rTriggerPrevious = false;
int _lTriggerLongPressCount = 0;
int _rTriggerLongPressCount = 0;
int _lTriggerLongPressMax = 500; // number of milliseconds until next pulsing of the key - automatically decreased with each press
int _rTriggerLongPressMax = 500;

std::vector<float> speeds; // contains actual speeds to choose
std::vector<std::string> speed_names; // contains pretty names of speeds to display
Expand Down Expand Up @@ -73,11 +77,29 @@ class Gopher
DWORD GAMEPAD_TRIGGER_LEFT = NULL;
DWORD GAMEPAD_TRIGGER_RIGHT = NULL;

// Key repeats (autofire)
int GAMEPAD_DPAD_UP_REPEAT = 0;
int GAMEPAD_DPAD_DOWN_REPEAT = 0;
int GAMEPAD_DPAD_LEFT_REPEAT = 0;
int GAMEPAD_DPAD_RIGHT_REPEAT = 0;
int GAMEPAD_START_REPEAT = 0;
int GAMEPAD_BACK_REPEAT = 0;
int GAMEPAD_LEFT_THUMB_REPEAT = 0;
int GAMEPAD_RIGHT_THUMB_REPEAT = 0;
int GAMEPAD_LEFT_SHOULDER_REPEAT = 0;
int GAMEPAD_RIGHT_SHOULDER_REPEAT = 0;
int GAMEPAD_A_REPEAT = 0;
int GAMEPAD_B_REPEAT = 0;
int GAMEPAD_X_REPEAT = 0;
int GAMEPAD_Y_REPEAT = 0;
int GAMEPAD_TRIGGER_LEFT_REPEAT = 0;
int GAMEPAD_TRIGGER_RIGHT_REPEAT = 0;

std::map<DWORD, bool> _xboxClickStateLastIteration;
std::map<DWORD, bool> _xboxClickIsDown;
std::map<DWORD, bool> _xboxClickIsDownLong;
std::map<DWORD, int> _xboxClickDownLength;
std::map<DWORD, int> _xboxClickDownLongMax;
std::map<DWORD, bool> _xboxClickIsUp;

CXBOXController* _controller;
Expand Down Expand Up @@ -112,7 +134,7 @@ class Gopher

bool xboxClickStateExists(DWORD xinput);

void mapKeyboard(DWORD STATE, WORD key);
void mapKeyboard(DWORD STATE, WORD key, int repeat);

void mapMouseClick(DWORD STATE, DWORD keyDown, DWORD keyUp);

Expand Down