orchard/src/renderer/main/gamepad.js
2022-08-04 05:27:29 +01:00

313 lines
8.8 KiB
JavaScript

function simulateGamepad() {
const app = window.app;
app.chrome.showCursor = true;
let cursorPos = [0, 0];
let intTabIndex = 0;
const cursorSpeedPvt = 8;
const cursorSize = 16;
let scrollSpeed = 8;
let buttonPressDelay = 500;
let stickDeadZone = 0.2;
let scrollGroup = null;
let scrollGroupY = null;
let elementFocusEnabled = true;
let start;
let cursorSpeed = cursorSpeedPvt;
let lastButtonPress = {};
var sounds = {
Confirm: new Audio("./sounds/confirm.ogg"),
Menu: new Audio("./sounds/btn1.ogg"),
Hover: new Audio("./sounds/hover.ogg"),
};
let element = document.elementFromPoint(0, 0);
let elementType = 0;
function appLoop() {
var gamepads = navigator.getGamepads ? navigator.getGamepads() : navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : [];
if (!gamepads) {
return;
}
var gp = gamepads[0];
// LEFT STICK
if (gp.axes[0] > stickDeadZone) {
cursorPos[0] += gp.axes[0] * cursorSpeed;
} else if (gp.axes[0] < -stickDeadZone) {
cursorPos[0] += gp.axes[0] * cursorSpeed;
}
if (gp.axes[1] > stickDeadZone) {
cursorPos[1] += gp.axes[1] * cursorSpeed;
} else if (gp.axes[1] < -stickDeadZone) {
cursorPos[1] += gp.axes[1] * cursorSpeed;
}
if (cursorPos[0] < cursorSize) {
cursorPos[0] = cursorSize;
}
if (cursorPos[1] < cursorSize) {
cursorPos[1] = cursorSize;
}
if (cursorPos[0] > window.innerWidth - cursorSize) {
cursorPos[0] = window.innerWidth - cursorSize;
}
if (cursorPos[1] > window.innerHeight - cursorSize) {
cursorPos[1] = window.innerHeight - cursorSize;
}
// RIGHT STICK.
if (scrollGroupY) {
if (gp.axes[3] > stickDeadZone) {
$(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + gp.axes[3] * scrollSpeed);
elementFocusEnabled = false;
} else if (gp.axes[3] < -stickDeadZone) {
$(scrollGroupY).scrollTop($(scrollGroupY).scrollTop() + gp.axes[3] * scrollSpeed);
elementFocusEnabled = false;
} else {
elementFocusEnabled = true;
}
}
if (scrollGroup) {
if (gp.axes[2] > stickDeadZone) {
$(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + gp.axes[2] * scrollSpeed);
elementFocusEnabled = false;
} else if (gp.axes[2] < -stickDeadZone) {
$(scrollGroup).scrollLeft($(scrollGroup).scrollLeft() + gp.axes[2] * scrollSpeed);
elementFocusEnabled = false;
} else {
elementFocusEnabled = true;
}
}
$(".cursor").css({
top: cursorPos[1] + "px",
left: cursorPos[0] + "px",
display: "block",
});
// A BUTTON
if (gp.buttons[0].pressed) {
if (!lastButtonPress["A"]) {
lastButtonPress["A"] = 0;
}
if (Date.now() - lastButtonPress["A"] > buttonPressDelay) {
lastButtonPress["A"] = Date.now();
sounds.Confirm.play();
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("click"));
document.activeElement.dispatchEvent(new Event("controller-click"));
} else {
element.dispatchEvent(new Event("click"));
element.dispatchEvent(new Event("controller-click"));
}
}
}
// B BUTTON
if (gp.buttons[1].pressed) {
if (!lastButtonPress["B"]) {
lastButtonPress["B"] = 0;
}
if (Date.now() - lastButtonPress["B"] > buttonPressDelay) {
lastButtonPress["B"] = Date.now();
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("contextmenu"));
setTimeout(() => {
if ($(".menu-option").length > 0) {
let bounds = $(".menu-option")[0].getBoundingClientRect();
cursorPos[0] = bounds.left + bounds.width / 2;
cursorPos[1] = bounds.top + bounds.height / 2;
}
}, 100);
} else {
element.dispatchEvent(new Event("contextmenu"));
}
}
}
// right bumper
if (gp.buttons[5].pressed) {
if (!lastButtonPress["RB"]) {
lastButtonPress["RB"] = 0;
}
if (Date.now() - lastButtonPress["RB"] > buttonPressDelay) {
lastButtonPress["RB"] = Date.now();
app.navigateForward();
}
}
// left bumper
if (gp.buttons[4].pressed) {
if (!lastButtonPress["LB"]) {
lastButtonPress["LB"] = 0;
}
if (Date.now() - lastButtonPress["LB"] > buttonPressDelay) {
lastButtonPress["LB"] = Date.now();
app.navigateBack();
}
}
// cursor hover
if (elementFocusEnabled) {
element = document.elementFromPoint(cursorPos[0], cursorPos[1]);
}
if (element) {
let closest = element.closest("[tabindex], input, button, a");
// VERT SCROLL
let scrollGroupCloY = element.closest(`[scrollaxis="y"]`);
if (scrollGroupCloY) {
scrollGroupY = scrollGroupCloY;
}
// HOZ SCROLL
let scrollGroupClo = element.closest(".v-hl-container");
if (scrollGroupClo) {
if (scrollGroupClo.classList.contains("v-hl-container")) {
scrollGroup = scrollGroupClo;
scrollGroup.style["scroll-snap-type"] = "unset";
} else {
scrollGroup.style["scroll-snap-type"] = "";
scrollGroup = null;
}
}
if (closest) {
elementType = 0;
closest.focus();
} else {
if (closest) {
closest.blur();
}
elementType = 1;
element.focus();
}
cursorSpeed = cursorSpeedPvt;
if (!element.classList.contains("app-chrome") && !element.classList.contains("app-content")) {
cursorSpeed = cursorSpeedPvt;
}
// console.log($._data($(element), "events"))
} else {
cursorSpeed = 12;
}
// console.log(gp.axes[0], gp.axes[1])
start = requestAnimationFrame(appLoop);
}
// controller pairing
notyf.error("Press the button on your controller to pair it to Cider.");
window.addEventListener(
"gamepadconnected",
function (e) {
console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.", e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length);
notyf.success("Pairing successful!");
appLoop();
},
{ once: true }
);
document.addEventListener("keydown", (e) => {
sounds.Confirm.currentTime = 0;
sounds.Menu.currentTime = 0;
sounds.Hover.currentTime = 0;
let tabbable = $("[tabindex]");
console.log(e.key);
switch (e.key) {
default:
break;
case "ArrowLeft":
e.preventDefault();
cursorPos[0] -= cursorSpeed;
break;
case "ArrowRight":
e.preventDefault();
cursorPos[0] += cursorSpeed;
break;
case "ArrowUp":
e.preventDefault();
cursorPos[1] -= cursorSpeed;
// sounds.Hover.play()
// if (intTabIndex <= 0) {
// intTabIndex = 0
// } else {
// intTabIndex--
// }
// $(tabbable[intTabIndex]).focus()
// $("#app-content").scrollTop($(document.activeElement).offset().top)
break;
case "ArrowDown":
e.preventDefault();
cursorPos[1] += cursorSpeed;
// if (intTabIndex < tabbable.length) {
// intTabIndex++
// } else {
// intTabIndex = tabbable.length
// }
// $(tabbable[intTabIndex]).focus()
// $("#app-content").scrollTop($(document.activeElement).offset().top)
break;
case "c":
app.resetState();
break;
case "x":
// set cursorPos to the top right of the screen
// sounds.Menu.play()
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("contextmenu"));
} else {
element.dispatchEvent(new Event("contextmenu"));
}
e.preventDefault();
break;
case "z":
sounds.Confirm.play();
if (elementType == 0) {
document.activeElement.dispatchEvent(new Event("click"));
document.activeElement.dispatchEvent(new Event("controller-click"));
} else {
element.dispatchEvent(new Event("click"));
element.dispatchEvent(new Event("controller-click"));
}
e.preventDefault();
break;
}
$(".cursor").css({
top: cursorPos[1] + "px",
left: cursorPos[0] + "px",
});
function lerp(a, b, n) {
return (1 - n) * a + n * b;
}
element = document.elementFromPoint(cursorPos[0], cursorPos[1]);
if (element) {
let closest = element.closest("[tabindex], input, button, a");
if (closest) {
elementType = 0;
closest.focus();
} else {
elementType = 1;
element.focus();
}
}
console.log(element);
});
}
export { simulateGamepad };