add DualSense skin
@ -95,6 +95,7 @@
|
|||||||
<select name="skin">
|
<select name="skin">
|
||||||
<option value="auto">Auto</option>
|
<option value="auto">Auto</option>
|
||||||
<option value="ds4">DualShock 4</option>
|
<option value="ds4">DualShock 4</option>
|
||||||
|
<option value="dualsense">DualSense</option>
|
||||||
<option value="xbox-one">Xbox One</option>
|
<option value="xbox-one">Xbox One</option>
|
||||||
<option value="debug">Debug</option>
|
<option value="debug">Debug</option>
|
||||||
<option value="telemetry">Telemetry</option>
|
<option value="telemetry">Telemetry</option>
|
||||||
|
@ -57,12 +57,19 @@ class Gamepad {
|
|||||||
name: 'Debug',
|
name: 'Debug',
|
||||||
},
|
},
|
||||||
ds4: {
|
ds4: {
|
||||||
id: /054c|54c|7545|09cc|0104|0ce6|046d|0810|2563/, // 054c,7545 = Sony vendor code, 09cc,0104 = DS4 controllers product codes, 0ce6 = DualSense controller product code, 046d,0810,2563 = PS-like controllers vendor codes
|
id: /05c4|09cc|0104|046d|0810|2563/, // 05c4,09cc,0104 = DS4 controllers product codes, 046d,0810,2563 = PS-like controllers vendor codes
|
||||||
name: 'DualShock 4',
|
name: 'DualShock 4',
|
||||||
colors: ['black', 'white', 'red', 'blue'],
|
colors: ['black', 'white', 'red', 'blue'],
|
||||||
triggers: true,
|
triggers: true,
|
||||||
zoom: true,
|
zoom: true,
|
||||||
},
|
},
|
||||||
|
dualsense: {
|
||||||
|
id: /0ce6/, // 0ce6 = DualSense controller product code
|
||||||
|
name: 'DualSense',
|
||||||
|
colors: ['white', 'black'],
|
||||||
|
triggers: true,
|
||||||
|
zoom: true,
|
||||||
|
},
|
||||||
// gamecube: {
|
// gamecube: {
|
||||||
// id: /0079/, // 0079 = Nintendo GameCube vendor code
|
// id: /0079/, // 0079 = Nintendo GameCube vendor code
|
||||||
// name: 'GameCube Controller',
|
// name: 'GameCube Controller',
|
||||||
@ -313,7 +320,7 @@ class Gamepad {
|
|||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
toGamepadInfo(id) {
|
toGamepadInfo(id) {
|
||||||
return /(?<name>.*) \(.*Vendor: (?<vendor>[0-9a-f]{4}) Product: (?<product>[0-9a-f]{4})\)/.exec(id).groups;
|
return /(?<name>.*?) \((Vendor: (?<vendor>[0-9a-f]{4}) Product: (?<product>[0-9a-f]{4})|(?<id>.*?))\)/.exec(id).groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,9 +334,9 @@ class Gamepad {
|
|||||||
if (!gamepad) {
|
if (!gamepad) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const { name, vendor, product } = this.toGamepadInfo(gamepad.id);
|
const { name } = this.toGamepadInfo(gamepad.id);
|
||||||
$options.push(
|
$options.push(
|
||||||
`<option class='entry' value='${vendor}-${product}'>${name}</option>`
|
`<option class='entry' value='${gamepad.id}'>${name}</option>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.$gamepadSelect.append($options.join(''));
|
this.$gamepadSelect.append($options.join(''));
|
||||||
@ -659,8 +666,7 @@ class Gamepad {
|
|||||||
this.identifier = this.identifiers[this.type];
|
this.identifier = this.identifiers[this.type];
|
||||||
|
|
||||||
// update the overlay selectors
|
// update the overlay selectors
|
||||||
const { vendor, product } = this.toGamepadInfo(gamepad.id);
|
this.$gamepadSelect.val(`${gamepad.id}`);
|
||||||
this.$gamepadSelect.val(`${vendor}-${product}`);
|
|
||||||
this.updateColors();
|
this.updateColors();
|
||||||
this.updateTriggers();
|
this.updateTriggers();
|
||||||
|
|
||||||
|
BIN
templates/dualsense/base-black.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
templates/dualsense/base-white.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
templates/dualsense/bumper.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
templates/dualsense/buttons.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
templates/dualsense/dpad.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
templates/dualsense/meta.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
templates/dualsense/select.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
templates/dualsense/start.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
templates/dualsense/sticks.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
276
templates/dualsense/template.css
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
#gamepad {
|
||||||
|
height: 700px;
|
||||||
|
width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad[data-color="black"] {
|
||||||
|
background-image: url(base-black.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad[data-color="white"] {
|
||||||
|
background-image: url(base-white.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad.disconnected div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .triggers {
|
||||||
|
width: 598px;
|
||||||
|
height: 90px;
|
||||||
|
position: absolute;
|
||||||
|
left: 299px;
|
||||||
|
top: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .trigger {
|
||||||
|
width: 99px;
|
||||||
|
height: 100%;
|
||||||
|
background: url(triggers.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .trigger[data-value="0"] {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .trigger.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .trigger.right {
|
||||||
|
float: right;
|
||||||
|
background-position-x: 99px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .bumper {
|
||||||
|
width: 200px;
|
||||||
|
height: 45px;
|
||||||
|
background: url(bumper.png) no-repeat;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .bumpers {
|
||||||
|
position: absolute;
|
||||||
|
width: 672px;
|
||||||
|
height: 23px;
|
||||||
|
left: 263px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad[data-color="black"] .bumpers {
|
||||||
|
top: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad[data-color="white"] .bumpers {
|
||||||
|
top: 132px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .bumper[data-pressed="true"] {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .bumper.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .bumper.right {
|
||||||
|
float: right;
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .touchpad {
|
||||||
|
width: 350px;
|
||||||
|
height: 300px;
|
||||||
|
position: absolute;
|
||||||
|
left: 422px;
|
||||||
|
top: 74px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .touchpad[data-pressed="true"] {
|
||||||
|
background: url(touchpad.png) no-repeat center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .meta {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
position: absolute;
|
||||||
|
left: 546px;
|
||||||
|
bottom: 264px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .meta[data-pressed="true"] {
|
||||||
|
background: url(meta.png) no-repeat center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .arrows {
|
||||||
|
position: absolute;
|
||||||
|
width: 352px;
|
||||||
|
height: 46px;
|
||||||
|
top: 142px;
|
||||||
|
left: 227px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .select,
|
||||||
|
#gamepad .start {
|
||||||
|
position: absolute;
|
||||||
|
width: 26px;
|
||||||
|
height: 43px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .select {
|
||||||
|
background: url(select.png);
|
||||||
|
left: 170px;
|
||||||
|
bottom: -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .start {
|
||||||
|
background: url(start.png);
|
||||||
|
left: 546px;
|
||||||
|
bottom: -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .select[data-pressed="true"],
|
||||||
|
#gamepad .start[data-pressed="true"] {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .select {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .start {
|
||||||
|
float: right;
|
||||||
|
background-position: 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .buttons {
|
||||||
|
position: absolute;
|
||||||
|
width: 170px;
|
||||||
|
height: 171px;
|
||||||
|
top: 200px;
|
||||||
|
left: 762px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .button {
|
||||||
|
position: absolute;
|
||||||
|
width: 55px;
|
||||||
|
height: 55px;
|
||||||
|
background: url(buttons.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .button[data-pressed="true"] {
|
||||||
|
background-position-y: 55px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .a {
|
||||||
|
background-position: 0 0;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 58px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .b {
|
||||||
|
background-position: -57px 0;
|
||||||
|
top: 57px;
|
||||||
|
right: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .x {
|
||||||
|
background-position: -113px 0;
|
||||||
|
top: 57px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .y {
|
||||||
|
background-position: 55px 0;
|
||||||
|
left: 58px;
|
||||||
|
bottom: 119px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .sticks {
|
||||||
|
position: absolute;
|
||||||
|
width: 364px;
|
||||||
|
height: 105px;
|
||||||
|
top: 348px;
|
||||||
|
left: 422px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .stick {
|
||||||
|
position: absolute;
|
||||||
|
background: url(sticks.png);
|
||||||
|
height: 94px;
|
||||||
|
width: 94px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .stick[data-pressed="true"].left {
|
||||||
|
background-position-x: -96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .stick[data-pressed="true"].right {
|
||||||
|
background-position-x: -192px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .stick.left {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .stick.right {
|
||||||
|
top: calc(100% - 105px);
|
||||||
|
left: calc(100% - 105px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .dpad {
|
||||||
|
position: absolute;
|
||||||
|
width: 125px;
|
||||||
|
height: 126px;
|
||||||
|
top: 220px;
|
||||||
|
left: 286px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face {
|
||||||
|
background: url(dpad.png);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.up,
|
||||||
|
#gamepad .face.down {
|
||||||
|
width: 37px;
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.left,
|
||||||
|
#gamepad .face.right {
|
||||||
|
width: 52px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.up {
|
||||||
|
left: 44px;
|
||||||
|
top: 0;
|
||||||
|
background-position: -37px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.down {
|
||||||
|
left: 44px;
|
||||||
|
bottom: 0;
|
||||||
|
background-position: 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.left {
|
||||||
|
top: 45px;
|
||||||
|
left: 0;
|
||||||
|
background-position: 104px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face.right {
|
||||||
|
top: 45px;
|
||||||
|
right: 0px;
|
||||||
|
background-position: 52px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad .face[data-pressed="true"] {
|
||||||
|
background-position-y: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gamepad.half {
|
||||||
|
margin-top: -300px;
|
||||||
|
}
|
35
templates/dualsense/template.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<link rel="stylesheet" href="templates/dualsense/template.css">
|
||||||
|
<script async src="templates/dualsense/template.js"></script>
|
||||||
|
<div class="triggers">
|
||||||
|
<span class="trigger left" data-button="6"></span>
|
||||||
|
<span class="trigger right" data-button="7"></span>
|
||||||
|
<span class="clear"></span>
|
||||||
|
</div>
|
||||||
|
<div class="bumpers">
|
||||||
|
<span class="bumper left" data-button="4"></span>
|
||||||
|
<span class="bumper right" data-button="5"></span>
|
||||||
|
<span class="clear"></span>
|
||||||
|
</div>
|
||||||
|
<div class="touchpad" data-button="17"></div>
|
||||||
|
<div class="meta" data-button="16"></div>
|
||||||
|
<div class="arrows">
|
||||||
|
<span class="select" data-button="8"></span>
|
||||||
|
<span class="start" data-button="9"></span>
|
||||||
|
<span class="clear"></span>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<span class="button a" data-button="0"></span>
|
||||||
|
<span class="button b" data-button="1"></span>
|
||||||
|
<span class="button x" data-button="2"></span>
|
||||||
|
<span class="button y" data-button="3"></span>
|
||||||
|
</div>
|
||||||
|
<div class="sticks">
|
||||||
|
<span class="stick left" data-button="10" data-axis-x="0" data-axis-y="1"></span>
|
||||||
|
<span class="stick right" data-button="11" data-axis-x="2" data-axis-y="3"></span>
|
||||||
|
</div>
|
||||||
|
<div class="dpad">
|
||||||
|
<span class="face up" data-button="12"></span>
|
||||||
|
<span class="face down" data-button="13"></span>
|
||||||
|
<span class="face left" data-button="14"></span>
|
||||||
|
<span class="face right" data-button="15"></span>
|
||||||
|
</div>
|
37
templates/dualsense/template.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
function DualShock4Template(gamepad) {
|
||||||
|
return {
|
||||||
|
init: function () {
|
||||||
|
gamepad.updateButton = function ($button) {
|
||||||
|
const value = parseFloat($button.attr('data-value'), 10);
|
||||||
|
if ($button.is('.trigger')) {
|
||||||
|
$button.css(
|
||||||
|
gamepad.triggersMeter
|
||||||
|
? {
|
||||||
|
opacity: 1,
|
||||||
|
'clip-path': `inset(${(1 - value) * 100}% 0px 0px 0pc)`,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
opacity: `${value * 100}%`,
|
||||||
|
'clip-path': 'none',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gamepad.updateAxis = function ($axis) {
|
||||||
|
const axisX = $axis.attr('data-value-x');
|
||||||
|
const axisY = $axis.attr('data-value-y');
|
||||||
|
if ($axis.is('.stick')) {
|
||||||
|
$axis.css({
|
||||||
|
'margin-top': axisY * 25,
|
||||||
|
'margin-left': axisX * 25,
|
||||||
|
transform: `rotateX(${-parseFloat(
|
||||||
|
axisY * 30,
|
||||||
|
8
|
||||||
|
)}deg) rotateY(${parseFloat(axisX * 30, 8)}deg)`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}.init();
|
||||||
|
};
|
||||||
|
new DualShock4Template(window.gamepad);
|
BIN
templates/dualsense/touchpad.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
templates/dualsense/triggers.png
Normal file
After Width: | Height: | Size: 4.4 KiB |