From 773a3c0d679f08ac006cd8ee3e853b7ced13f15f Mon Sep 17 00:00:00 2001 From: LizardByte-bot <108553330+LizardByte-bot@users.noreply.github.com> Date: Sat, 3 May 2025 18:24:12 +0000 Subject: [PATCH] Deploy site from a70cf5e12ec610999b1979442e0bca120c6ac179 --- 404.html | 2 + assets/css/styles.css | 2 +- assets/js/gamepad-helper.js | 362 ------------------------------------ assets/js/gamepad-tester.js | 83 +++++---- index.html | 2 + tags/index.html | 2 + 6 files changed, 55 insertions(+), 398 deletions(-) delete mode 100644 assets/js/gamepad-helper.js diff --git a/404.html b/404.html index 29e487f2..c5fdc30d 100644 --- a/404.html +++ b/404.html @@ -419,6 +419,8 @@ Privacy  •  Terms + •  +Licenses diff --git a/assets/css/styles.css b/assets/css/styles.css index 288ca7ec..0144a9d3 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -1 +1 @@ -.admonition{margin:1.5625em 0;overflow:hidden;color:var(--text-col);page-break-inside:avoid;background-color:var(--navbar-col);border-left:0.3rem solid #fc0;border-radius:.1rem}.admonition p{padding:0 1rem}.admonition .admonition-title{color:var(--text-col);background-color:rgba(142,113,0,0.4);font-weight:700;line-height:3rem}.admonition-title::before{margin-right:.5rem;width:1.2rem;height:1.2rem;display:inline-block;content:'';-webkit-mask-size:cover;mask-size:cover;background-color:#fc0;vertical-align:text-bottom}.admonition.attention{border-left-color:#ff5252}.admonition.attention .admonition-title{background-color:#564444}.admonition.attention .admonition-title::before{-webkit-mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.caution{border-left-color:#ff9100}.admonition.caution .admonition-title{background-color:#564b3c}.admonition.caution .admonition-title::before{-webkit-mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;background-color:#ff9100}.admonition.danger{border-left-color:#ff5252}.admonition.danger .admonition-title{background-color:#564444}.admonition.danger .admonition-title::before{-webkit-mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.error{border-left-color:#ff5252}.admonition.error .admonition-title{background-color:#564444}.admonition.error .admonition-title::before{-webkit-mask:url("/assets/img/icons/times-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/times-circle-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.hint{border-left-color:#00c953}.admonition.hint .admonition-title{background-color:#294040}.admonition.hint .admonition-title::before{-webkit-mask:url("/assets/img/icons/question-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/question-circle-solid.svg") no-repeat 50% 50%;background-color:#00c953}.admonition.important{border-left-color:#ff9100}.admonition.important .admonition-title{background-color:#433a38}.admonition.important .admonition-title::before{-webkit-mask:url("/assets/img/icons/fire-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/fire-solid.svg") no-repeat 50% 50%;background-color:#ff9100}.admonition.note{border-left-color:#00b0ff}.admonition.note .admonition-title{background-color:#293d52}.admonition.note .admonition-title::before{-webkit-mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;background-color:#00b0ff}.admonition.seealso{border-left-color:#00b0ff}.admonition.seealso .admonition-title{background-color:#293d52}.admonition.seealso .admonition-title::before{-webkit-mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;background-color:#00b0ff}.admonition.tip{border-left-color:#00c953}.admonition.tip .admonition-title{background-color:#294040}.admonition.tip .admonition-title::before{-webkit-mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;background-color:#00c953}.admonition.todo .admonition-title::before{-webkit-mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%}.admonition.warning{border-left-color:#ff9100}.admonition.warning .admonition-title{background-color:#564b3c}.admonition.warning .admonition-title::before{-webkit-mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;background-color:#ff9100}body{font-family:'Open Sans', sans-serif}.box-error,.box-note,.box-warning{color:#18191a}.avatar-img{background-color:var(--navbar-col);border:.05rem;border-color:var(--navbar-border-col);border-style:solid}.card-body,.card-custom,.card-footer,.card-img-top,.cr-picker-button,.cr-picker-submenu{--bs-bg-opacity: 1;background-color:var(--navbar-col) !important}.modal-content{background-color:var(--footer-col) !important}code{color:var(--mid-col);background-color:var(--navbar-col)}.feature{display:inline-flex;align-items:center;justify-content:center;height:3rem;width:3rem;font-size:1.5rem}.widgetbot{display:flex;align-items:center;justify-content:space-around}.pagination .page-item .page-link{background-color:#111111;color:#e4e4e4}.navbar-custom.top-nav-short .avatar-container{width:3.125rem;opacity:1 !important;visibility:visible !important;transition:none !important;-webkit-transition:none !important;-moz-transition:none !important}#nav-search-link{display:none}.hover-zoom{overflow:hidden}.hover-zoom img{transition:all 1.5s ease}.hover-zoom:hover img{transform:scale(1.1)}.icon img,img.icon{max-width:none;height:2.25em}.icon-sm img,img.icon-sm{max-width:none;height:1.25em}.icon-lg img,img.icon-lg{max-width:none;height:3.25em}img.invert{filter:invert(1)}.btn:hover img.invert{filter:invert(0)}.highlight{border-radius:0.5rem}.highlight>pre{border-left:0.4375rem solid var(--text-col)}.highlight pre.lineno{border-right:2px solid var(--text-col)}.admonition .highlight{margin-left:0.5rem;margin-right:1.25rem}.admonition .highlight>pre{border-radius:0.5rem}.tabs{background-color:var(--footer-col);padding:1rem}.tabs .nav-link{color:var(--link-col)}.tabs .nav-link:hover{color:var(--hover-col)}.tabs .nav-link.active{color:var(--text-col);border-color:var(--text-col)}.tab-content{background-color:var(--navbar-col);padding:1rem;margin-top:1rem;border:1px solid var(--page-col);border-radius:0.5rem}table tr:nth-child(2n){background-color:var(--footer-col)}.circular-button{position:relative;width:70px;height:70px;line-height:70px;background:none;margin-right:8px;margin-bottom:8px;display:flex;justify-content:center;align-items:center}.circular-button:after{content:"";width:100%;height:100%;border-radius:50%;border:5px solid #2b3035;position:absolute;top:0;left:0}.circular-button>span{width:50%;height:100%;overflow:hidden;position:absolute;top:0;z-index:1}.circular-button .progress-left{left:0.5px}.circular-button .progress-right{right:0.5px}.circular-button .progress-bar{width:100%;height:100%;background:none;border-width:5px;border-style:solid;position:absolute;top:0}.circular-button .progress-left .progress-bar{left:100%;border-top-right-radius:35px;border-bottom-right-radius:35px;border-left:0;transform-origin:center left}.circular-button .progress-right .progress-bar{left:-100%;border-top-left-radius:35px;border-bottom-left-radius:35px;border-right:0;transform-origin:center right}.circular-button .button-content{width:80%;height:80%;border-radius:50%;background:#2b3035;display:flex;flex-direction:column;justify-content:center;align-items:center;position:absolute;top:10%;left:10%;z-index:2;text-align:center}.circular-button .button-name{font-weight:bold;margin-bottom:2px;line-height:1.2}.circular-button .button-value{font-size:0.85rem;line-height:1}.circular-button .progress-bar{border-color:#0d6efd}.circular-button.active .button-content{box-shadow:0 0 10px 3px rgba(13,110,253,0.5)} +.admonition{margin:1.5625em 0;overflow:hidden;color:var(--text-col);page-break-inside:avoid;background-color:var(--navbar-col);border-left:0.3rem solid #fc0;border-radius:.1rem}.admonition p{padding:0 1rem}.admonition .admonition-title{color:var(--text-col);background-color:rgba(142,113,0,0.4);font-weight:700;line-height:3rem}.admonition-title::before{margin-right:.5rem;width:1.2rem;height:1.2rem;display:inline-block;content:'';-webkit-mask-size:cover;mask-size:cover;background-color:#fc0;vertical-align:text-bottom}.admonition.attention{border-left-color:#ff5252}.admonition.attention .admonition-title{background-color:#564444}.admonition.attention .admonition-title::before{-webkit-mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.caution{border-left-color:#ff9100}.admonition.caution .admonition-title{background-color:#564b3c}.admonition.caution .admonition-title::before{-webkit-mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;background-color:#ff9100}.admonition.danger{border-left-color:#ff5252}.admonition.danger .admonition-title{background-color:#564444}.admonition.danger .admonition-title::before{-webkit-mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/bolt-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.error{border-left-color:#ff5252}.admonition.error .admonition-title{background-color:#564444}.admonition.error .admonition-title::before{-webkit-mask:url("/assets/img/icons/times-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/times-circle-solid.svg") no-repeat 50% 50%;background-color:#ff5252}.admonition.hint{border-left-color:#00c953}.admonition.hint .admonition-title{background-color:#294040}.admonition.hint .admonition-title::before{-webkit-mask:url("/assets/img/icons/question-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/question-circle-solid.svg") no-repeat 50% 50%;background-color:#00c953}.admonition.important{border-left-color:#ff9100}.admonition.important .admonition-title{background-color:#433a38}.admonition.important .admonition-title::before{-webkit-mask:url("/assets/img/icons/fire-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/fire-solid.svg") no-repeat 50% 50%;background-color:#ff9100}.admonition.note{border-left-color:#00b0ff}.admonition.note .admonition-title{background-color:#293d52}.admonition.note .admonition-title::before{-webkit-mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;background-color:#00b0ff}.admonition.seealso{border-left-color:#00b0ff}.admonition.seealso .admonition-title{background-color:#293d52}.admonition.seealso .admonition-title::before{-webkit-mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;background-color:#00b0ff}.admonition.tip{border-left-color:#00c953}.admonition.tip .admonition-title{background-color:#294040}.admonition.tip .admonition-title::before{-webkit-mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/info-circle-solid.svg") no-repeat 50% 50%;background-color:#00c953}.admonition.todo .admonition-title::before{-webkit-mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/pen-solid.svg") no-repeat 50% 50%}.admonition.warning{border-left-color:#ff9100}.admonition.warning .admonition-title{background-color:#564b3c}.admonition.warning .admonition-title::before{-webkit-mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;mask:url("/assets/img/icons/exclamation-triangle-solid.svg") no-repeat 50% 50%;background-color:#ff9100}body{font-family:'Open Sans', sans-serif}.box-error,.box-note,.box-warning{color:#18191a}.avatar-img{background-color:var(--navbar-col);border:.05rem;border-color:var(--navbar-border-col);border-style:solid}.card-body,.card-custom,.card-footer,.card-img-top,.cr-picker-button,.cr-picker-submenu{--bs-bg-opacity: 1;background-color:var(--navbar-col) !important}.modal-content{background-color:var(--footer-col) !important}code{color:var(--mid-col);background-color:var(--navbar-col)}.feature{display:inline-flex;align-items:center;justify-content:center;height:3rem;width:3rem;font-size:1.5rem}.widgetbot{display:flex;align-items:center;justify-content:space-around}.pagination .page-item .page-link{background-color:#111111;color:#e4e4e4}.navbar-custom.top-nav-short .avatar-container{width:3.125rem;opacity:1 !important;visibility:visible !important;transition:none !important;-webkit-transition:none !important;-moz-transition:none !important}#nav-search-link{display:none}.hover-zoom{overflow:hidden}.hover-zoom img{transition:all 1.5s ease}.hover-zoom:hover img{transform:scale(1.1)}.icon img,img.icon{max-width:none;height:2.25em}.icon-sm img,img.icon-sm{max-width:none;height:1.25em}.icon-lg img,img.icon-lg{max-width:none;height:3.25em}img.invert{filter:invert(1)}.btn:hover img.invert{filter:invert(0)}.highlight{border-radius:0.5rem}.highlight>pre{border-left:0.4375rem solid var(--text-col)}.highlight pre.lineno{border-right:2px solid var(--text-col)}.admonition .highlight{margin-left:0.5rem;margin-right:1.25rem}.admonition .highlight>pre{border-radius:0.5rem}.tabs{background-color:var(--footer-col);padding:1rem}.tabs .nav-link{color:var(--link-col)}.tabs .nav-link:hover{color:var(--hover-col)}.tabs .nav-link.active{color:var(--text-col);border-color:var(--text-col)}.tab-content{background-color:var(--navbar-col);padding:1rem;margin-top:1rem;border:1px solid var(--page-col);border-radius:0.5rem}table tr:nth-child(2n){background-color:var(--footer-col)}.list-group-item.bg-dark{border-color:var(--navbar-col)}.list-group-item.bg-dark .text-muted{color:var(--text-col)}.list-group-item.bg-dark a{text-decoration:none}.list-group-item.bg-dark a:hover{text-decoration:underline}.circular-button{position:relative;width:70px;height:70px;line-height:70px;background:none;margin-right:8px;margin-bottom:8px;display:flex;justify-content:center;align-items:center}.circular-button:after{content:"";width:100%;height:100%;border-radius:50%;border:5px solid #2b3035;position:absolute;top:0;left:0}.circular-button>span{width:50%;height:100%;overflow:hidden;position:absolute;top:0;z-index:1}.circular-button .progress-left{left:0.5px}.circular-button .progress-right{right:0.5px}.circular-button .progress-bar{width:100%;height:100%;background:none;border-width:5px;border-style:solid;position:absolute;top:0}.circular-button .progress-left .progress-bar{left:100%;border-top-right-radius:35px;border-bottom-right-radius:35px;border-left:0;transform-origin:center left}.circular-button .progress-right .progress-bar{left:-100%;border-top-left-radius:35px;border-bottom-left-radius:35px;border-right:0;transform-origin:center right}.circular-button .button-content{width:80%;height:80%;border-radius:50%;background:#2b3035;display:flex;flex-direction:column;justify-content:center;align-items:center;position:absolute;top:10%;left:10%;z-index:2;text-align:center}.circular-button .button-name{font-weight:bold;margin-bottom:2px;line-height:1.2}.circular-button .button-value{font-size:0.85rem;line-height:0.5}.circular-button .progress-bar{border-color:#0d6efd}.circular-button.active .button-content{box-shadow:0 0 10px 3px rgba(13,110,253,0.5)}.circular-button .button-image-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%}.circular-button .button-image{max-width:2.5rem;max-height:2.5rem;width:auto;height:auto} diff --git a/assets/js/gamepad-helper.js b/assets/js/gamepad-helper.js deleted file mode 100644 index aa6c5b93..00000000 --- a/assets/js/gamepad-helper.js +++ /dev/null @@ -1,362 +0,0 @@ -// GamepadHelper library -const GamepadHelper = (function() { - // Controller type definitions - const CONTROLLER_TYPES = { - XBOX: 'xbox', - PLAYSTATION: 'playstation', - SWITCH: 'switch', - STANDARD: 'standard' - }; - - // Exact gamepad ID mappings with numbered indices - const exactGamepadMappings = { - 0: { - name: "Generic Gamepad", - gamepad_api_ids: [ - "USB Gamepad (STANDARD GAMEPAD Vendor: 0079 Product: 0011)", - "Logitech Cordless RumblePad 2 (STANDARD GAMEPAD Vendor: 046d Product: c219)", - "Unknown Gamepad (Vendor: 2563 Product: 0575)", - "PC/PS3/Android (Vendor: 2563 Product: 0575)", - "Core (Plus) Wired Controller (Vendor: 20d6 Product: a711)", - "Wireless Controller Extended Gamepad", - ], - type: CONTROLLER_TYPES.STANDARD, - }, - 1: { - name: "Sony PlayStation 3", - gamepad_api_ids: [ - "54c-268-PLAYSTATION(R)3 Controller", - "PLAYSTATION(R)3 Controller (STANDARD GAMEPAD Vendor: 054c Product: 0268)", - "PLAYSTATION(R)3 Controller (Vendor: 054c Product: 0268)", - "PS3 GamePad (Vendor: 054c Product: 0268)", - "PS3/PC Wired GamePad (Vendor: 2563 Product: 0523)", - ], - type: CONTROLLER_TYPES.PLAYSTATION - }, - 2: { - name: "Sony DualShock (PS4)", - gamepad_api_ids: [ - "054c-05c4-Wireless Controller", - "Wireless controller (STANDARD GAMEPAD Vendor: 054c Product: 05c4)", - "054c-09cc-Unknown Gamepad", - "Unknown Gamepad (STANDARD GAMEPAD Vendor: 054c Product: 09cc)", - "DS4 Wired Controller (Vendor: 7545 Product: 0104)", - ], - type: CONTROLLER_TYPES.PLAYSTATION - }, - 3: { - name: "Sony DualSense (PS5)", - gamepad_api_ids: [ - "054c-0ce6-Wireless Controller", - "Wireless Controller (Vendor: 054c Product: 0ce6)", - "Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 0ce6)", - ], - type: CONTROLLER_TYPES.PLAYSTATION - }, - 4: { - name: "Xbox", - gamepad_api_ids: [ - "xinput", - "Xbox Wireless Controller Extended Gamepad", - "Xbox Wireless Controller", - ], - type: CONTROLLER_TYPES.XBOX - }, - 5: { - name: "Xbox 360", - gamepad_api_ids: [ - ], - type: CONTROLLER_TYPES.XBOX - }, - 6: { - name: "Xbox One/Series", - gamepad_api_ids: [ - "HID-compliant game controller (STANDARD GAMEPAD Vendor: 045e Product: 0b13)", - ], - type: CONTROLLER_TYPES.XBOX - }, - 7: { - name: "Nintendo Switch Pro Controller", - gamepad_api_ids: [ - "Pro Controller (STANDARD GAMEPAD Vendor: 057e Product: 2009)", - ], - type: CONTROLLER_TYPES.SWITCH - }, - 8: { - name: "Stadia Controller", - gamepad_api_ids: [ - "Stadia Controller rev. A (STANDARD GAMEPAD Vendor: 18d1 Product: 9400)", - ], - type: CONTROLLER_TYPES.STANDARD, - }, - 9: { - name: "SNES Gamepad", - gamepad_api_ids: [ - "usb gamepad (Vendor: 0810 Product: e501)", - ], - type: CONTROLLER_TYPES.STANDARD, - } - }; - - // Build a lookup map for fast exact matching - const exactIdLookup = {}; - Object.values(exactGamepadMappings).forEach(mapping => { - mapping.gamepad_api_ids.forEach(id => { - exactIdLookup[id] = mapping; - }); - }); - - // Controller mappings with regex patterns for fallback detection - const controllerMappings = { - // Xbox controllers - [CONTROLLER_TYPES.XBOX]: { - buttonMap: { - 0: 'A', - 1: 'B', - 2: 'X', - 3: 'Y', - 4: 'LB', - 5: 'RB', - 6: 'LT', - 7: 'RT', - 8: 'Back', - 9: 'Start', - 10: 'LS', - 11: 'RS', - 12: 'DUp', - 13: 'DDown', - 14: 'DLeft', - 15: 'DRight', - 16: 'Home', - }, - axisMap: { - 0: 'Left Stick X', - 1: 'Left Stick Y', - 2: 'Right Stick X', - 3: 'Right Stick Y' - } - }, - - // PlayStation controllers - [CONTROLLER_TYPES.PLAYSTATION]: { - buttonMap: { - 0: '×', - 1: '○', - 2: '□', - 3: '△', - 4: 'L1', - 5: 'R1', - 6: 'L2', - 7: 'R2', - 8: 'Share', - 9: 'Options', - 10: 'L3', - 11: 'R3', - 12: 'DUp', - 13: 'DDown', - 14: 'DLeft', - 15: 'DRight', - 16: 'PS', - 17: 'TouchPad', - }, - axisMap: { - 0: 'Left Stick X', - 1: 'Left Stick Y', - 2: 'Right Stick X', - 3: 'Right Stick Y' - } - }, - - // Nintendo Switch controllers - [CONTROLLER_TYPES.SWITCH]: { - buttonMap: { - 0: 'B', - 1: 'A', - 2: 'Y', - 3: 'X', - 4: 'L', - 5: 'R', - 6: 'ZL', - 7: 'ZR', - 8: 'Minus', - 9: 'Plus', - 10: 'LS', - 11: 'RS', - 12: 'DUp', - 13: 'DDown', - 14: 'DLeft', - 15: 'DRight', - 16: 'Home', - 17: 'Capture', - }, - axisMap: { - 0: 'Left Stick X', - 1: 'Left Stick Y', - 2: 'Right Stick X', - 3: 'Right Stick Y' - } - }, - - // Default mapping for unknown controllers - [CONTROLLER_TYPES.STANDARD]: { - buttonMap: {}, // Will use index numbers by default - axisMap: { - 0: 'Axis 0', - 1: 'Axis 1', - 2: 'Axis 2', - 3: 'Axis 3' - } - } - }; - - // Check if Gamepad API is supported - function isSupported() { - return !!navigator.getGamepads; - } - - // Get gamepad info - combines exact matching with regex fallback - function getGamepadInfo(gamepadId) { - if (!gamepadId) { - return { - type: CONTROLLER_TYPES.STANDARD, - name: 'Generic Controller' - }; - } - - // Check for exact match first - const exactMatch = exactIdLookup[gamepadId]; - if (exactMatch) { - return { - type: exactMatch.type, - name: exactMatch.name - }; - } - - return { - type: CONTROLLER_TYPES.STANDARD, - name: 'Generic Controller' - }; - } - - // Detect controller type from gamepad ID (simplified version for backward compatibility) - function detectControllerType(gamepadId) { - return getGamepadInfo(gamepadId).type; - } - - // Get button name for given controller type and button index - function getButtonName(controllerType, buttonIndex) { - const mapping = controllerMappings[controllerType] || controllerMappings[CONTROLLER_TYPES.STANDARD]; - return mapping.buttonMap[buttonIndex] || `B${buttonIndex}`; - } - - // Get axis name for given controller type and axis index - function getAxisName(controllerType, axisIndex) { - const mapping = controllerMappings[controllerType] || controllerMappings[CONTROLLER_TYPES.STANDARD]; - return mapping.axisMap && mapping.axisMap[axisIndex] || `Axis ${axisIndex}`; - } - - /// Detect if vibration is supported and return support information - function isVibrationSupported(gamepad) { - if (!gamepad || !gamepad.vibrationActuator) return false; - - // Return true for any actuator type, not just dual-rumble - return true; - } - - // Get detailed information about vibration capabilities - function getVibrationCapabilities(gamepad) { - if (!gamepad || !gamepad.vibrationActuator) { - return { supported: false, type: null }; - } - - return { - supported: true, - type: gamepad.vibrationActuator.type || 'unknown' - }; - } - - // Apply vibration if supported, with adaptive behavior for different actuator types - function vibrate(gamepad, options = {}) { - const { weakMagnitude = 0.5, strongMagnitude = 0.5, duration = 1000, startDelay = 0 } = options; - - if (!gamepad || !gamepad.vibrationActuator) { - return Promise.reject(new Error('Vibration not supported on this gamepad')); - } - - const actuator = gamepad.vibrationActuator; - const actuatorType = actuator.type || 'unknown'; - - // Different handling based on actuator type - switch (actuatorType) { - case 'dual-rumble': - return actuator.playEffect("dual-rumble", { - startDelay: startDelay, - duration: duration, - weakMagnitude: weakMagnitude, - strongMagnitude: strongMagnitude - }); - - case 'vibration': - // Some devices just have a simple vibration effect - const magnitude = Math.max(weakMagnitude, strongMagnitude); - return actuator.playEffect("vibration", { - startDelay: startDelay, - duration: duration, - magnitude: magnitude - }); - - default: - // Try the default effect type for unknown actuators - try { - return actuator.playEffect(actuator.type, { - startDelay: startDelay, - duration: duration, - weakMagnitude: weakMagnitude, - strongMagnitude: strongMagnitude, - magnitude: Math.max(weakMagnitude, strongMagnitude) - }); - } catch (e) { - console.warn(`Attempted to use unknown actuator type: ${actuatorType}`); - // Fallback to dual-rumble as it's the most common - return actuator.playEffect("dual-rumble", { - startDelay: startDelay, - duration: duration, - weakMagnitude: weakMagnitude, - strongMagnitude: strongMagnitude - }); - } - } - } - - // Stop vibration - function stopVibration(gamepad) { - if (gamepad && gamepad.vibrationActuator) { - return vibrate(gamepad, { weakMagnitude: 0, strongMagnitude: 0 }); - } - - return Promise.reject(new Error('Vibration not supported on this browser or gamepad')); - } - - // Get all connected gamepads - function getConnectedGamepads() { - if (!isSupported()) return []; - - const gamepads = navigator.getGamepads(); - return Array.from(gamepads).filter(gamepad => gamepad !== null); - } - - // Public API - return { - isSupported, - detectControllerType, - getGamepadInfo, - getButtonName, - getAxisName, - isVibrationSupported, - getVibrationCapabilities, - vibrate, - stopVibration, - getConnectedGamepads, - CONTROLLER_TYPES - }; -})(); diff --git a/assets/js/gamepad-tester.js b/assets/js/gamepad-tester.js index 20db95cb..98d66210 100644 --- a/assets/js/gamepad-tester.js +++ b/assets/js/gamepad-tester.js @@ -1,4 +1,6 @@ document.addEventListener('DOMContentLoaded', function() { + const gamepadHelper = new GamepadHelper() + const gamepadHelperVersion = window.gamepadHelperVersion; let gamepads = {}; let activeGamepadIndex = null; let animationFrameId = null; @@ -8,27 +10,13 @@ document.addEventListener('DOMContentLoaded', function() { let gamepadStatus = document.getElementById('gamepad-status'); // Check if the Gamepad API is supported - if (!GamepadHelper.isSupported()) { + if (!gamepadHelper.isSupported()) { gamepadStatus.textContent = 'Gamepad API not supported in this browser'; gamepadStatus.classList.remove('alert-warning'); gamepadStatus.classList.add('alert-danger'); return; } - // Initialize button colors for various states - const buttonColors = { - 'standard': { - 'inactive': 'btn-outline-primary', - 'active': 'btn-primary' - }, - }; - - // Axis names mapping - const axisNames = [ - 'Left Stick X', 'Left Stick Y', - 'Right Stick X', 'Right Stick Y' - ]; - // Setup gamepad event listeners window.addEventListener("gamepadconnected", function(e) { gamepads[e.gamepad.index] = e.gamepad; @@ -129,27 +117,52 @@ document.addEventListener('DOMContentLoaded', function() { const gamepad = navigator.getGamepads()[activeGamepadIndex]; if (!gamepad) return; - const controllerType = GamepadHelper.detectControllerType(gamepad.id); + const controllerType = gamepadHelper.detectControllerType(gamepad.id); for (let i = 0; i < gamepad.buttons.length; i++) { - const buttonName = GamepadHelper.getButtonName(controllerType, i); + const buttonName = gamepadHelper.getButtonName(controllerType, i); + const buttonImagePath = gamepadHelper.getButtonImagePath( + controllerType, + i, + `https://cdn.jsdelivr.net/npm/@lizardbyte/gamepad-helper@${gamepadHelperVersion}/assets/img/gamepads/`, + ); const buttonDiv = document.createElement('div'); buttonDiv.className = 'circular-button'; buttonDiv.id = `button-${i}`; - buttonDiv.innerHTML = ` - - - - - - -
+ // Create the progress elements + const progressLeft = document.createElement('span'); + progressLeft.className = 'progress-left'; + progressLeft.innerHTML = ``; + + const progressRight = document.createElement('span'); + progressRight.className = 'progress-right'; + progressRight.innerHTML = ``; + + // Create the button content + const buttonContent = document.createElement('div'); + buttonContent.className = 'button-content'; + + // Add either image with fallback text, or just text + if (buttonImagePath) { + buttonContent.innerHTML = ` +
+ ${buttonName} + +
+
0.00
+ `; + } else { + buttonContent.innerHTML = `
${buttonName}
0.00
-
- `; + `; + } + + buttonDiv.appendChild(progressLeft); + buttonDiv.appendChild(progressRight); + buttonDiv.appendChild(buttonContent); buttonsContainer.appendChild(buttonDiv); } @@ -165,13 +178,13 @@ document.addEventListener('DOMContentLoaded', function() { const gamepad = navigator.getGamepads()[activeGamepadIndex]; if (!gamepad) return; - const controllerType = GamepadHelper.detectControllerType(gamepad.id); + const controllerType = gamepadHelper.detectControllerType(gamepad.id); for (let i = 0; i < gamepad.axes.length; i++) { const colDiv = document.createElement('div'); colDiv.className = 'col-md-6 col-lg-3 mb-3'; - const axisName = GamepadHelper.getAxisName(controllerType, i); + const axisName = gamepadHelper.getAxisName(controllerType, i); colDiv.innerHTML = `
${axisName}: 0.00
@@ -201,8 +214,8 @@ document.addEventListener('DOMContentLoaded', function() { // Update the gamepad info function to include vibration status function updateGamepadInfo(gamepad) { - const gamepadInfo = GamepadHelper.getGamepadInfo(gamepad.id); - const vibrationCapabilities = GamepadHelper.getVibrationCapabilities(gamepad); + const gamepadInfo = gamepadHelper.getGamepadInfo(gamepad.id); + const vibrationCapabilities = gamepadHelper.getVibrationCapabilities(gamepad); document.getElementById('gamepad-id').textContent = gamepad.id; document.getElementById('gamepad-index').textContent = gamepad.index; @@ -367,7 +380,7 @@ document.addEventListener('DOMContentLoaded', function() { return `Axis ${index}: ${axis.toFixed(2)}`; }); - rawDataElement.textContent = `Gamepad: ${gamepad.id}\nType: ${GamepadHelper.detectControllerType(gamepad.id)}\n\nButtons:\n${buttons.join('\n')}\n\nAxes:\n${axes.join('\n')}`; + rawDataElement.textContent = `Gamepad: ${gamepad.id}\nType: ${gamepadHelper.detectControllerType(gamepad.id)}\n\nButtons:\n${buttons.join('\n')}\n\nAxes:\n${axes.join('\n')}`; } // Event listeners for vibration controls @@ -393,7 +406,7 @@ document.addEventListener('DOMContentLoaded', function() { const gamepad = navigator.getGamepads()[activeGamepadIndex]; if (!gamepad) return; - const vibrationCapabilities = GamepadHelper.getVibrationCapabilities(gamepad); + const vibrationCapabilities = gamepadHelper.getVibrationCapabilities(gamepad); if (!vibrationCapabilities.supported) return; const duration = parseInt(document.getElementById('vibration-duration').value); @@ -409,7 +422,7 @@ document.addEventListener('DOMContentLoaded', function() { vibrationOptions.magnitude = magnitude; } - GamepadHelper.vibrate(gamepad, vibrationOptions) + gamepadHelper.vibrate(gamepad, vibrationOptions) .then(() => console.log('Vibration started')) .catch(e => console.error('Vibration error:', e)); } @@ -420,7 +433,7 @@ document.addEventListener('DOMContentLoaded', function() { if (activeGamepadIndex !== null) { const gamepad = navigator.getGamepads()[activeGamepadIndex]; if (gamepad) { - GamepadHelper.stopVibration(gamepad).catch(e => { + gamepadHelper.stopVibration(gamepad).catch(e => { console.error('Stop vibration error:', e); }); } diff --git a/index.html b/index.html index c4356220..4e732791 100644 --- a/index.html +++ b/index.html @@ -1115,6 +1115,8 @@ Privacy  •  Terms + •  +Licenses diff --git a/tags/index.html b/tags/index.html index e90d0088..98f1c88b 100644 --- a/tags/index.html +++ b/tags/index.html @@ -447,6 +447,8 @@ Privacy  •  Terms + •  +Licenses