Stadia Controller ที่แฟลชจะทำงานเหมือนเกมแพดมาตรฐาน ซึ่งหมายความว่าปุ่มบางปุ่มจะเข้าถึงไม่ได้โดยใช้ Gamepad API ตอนนี้คุณเข้าถึงปุ่มที่หายไปได้แล้วด้วย WebHID
เนื่องจาก Stadia ปิดตัวลง หลายคนจึงกังวลว่าตัวควบคุมจะกลายเป็นฮาร์ดแวร์ที่ไร้ประโยชน์ในกองขยะ โชคดีที่ทีม Stadia ตัดสินใจที่จะเปิด Stadia Controller แทน โดยการจัดเฟิร์มแวร์ที่กำหนดเองซึ่งคุณสามารถแฟลชในตัวควบคุมได้โดยไปที่หน้าโหมดบลูทูธของ Stadia การดำเนินการนี้จะทำให้ Stadia Controller ปรากฏเป็นเกมแพดมาตรฐานที่คุณเชื่อมต่อได้ผ่านสาย USB หรือแบบไร้สายผ่านบลูทูธ หน้า Bluetooth ของ Stadia ซึ่งแสดงอย่างภาคภูมิใจใน Project Fugu API Showcase ใช้ WebHID และ WebUSB แต่ไม่ใช่หัวข้อของบทความนี้ ในโพสต์นี้ ฉันจะอธิบายวิธีพูดกับ Stadia Controller ผ่าน WebHID
Stadia Controller เป็นเกมแพดมาตรฐาน
หลังจากแฟลชแล้ว ตัวควบคุมจะปรากฏเป็นเกมแพดมาตรฐานในระบบปฏิบัติการ ดูภาพหน้าจอต่อไปนี้เพื่อดูการจัดเรียงปุ่มและแกนทั่วไปในเกมแพดมาตรฐาน ตามที่กำหนดไว้ในข้อกำหนด Gamepad API เกมแพดมาตรฐานมีปุ่มตั้งแต่ 0 ถึง 16 รวมเป็น 17 ปุ่ม (ปุ่ม D-pad นับเป็น 4 ปุ่ม) หากลองใช้ Stadia Controller ในการสาธิตเครื่องมือทดสอบเกมแพด คุณจะเห็นว่าใช้งานได้ดี
แต่หากนับปุ่มบน Stadia Controller จะมี 19 ปุ่ม หากคุณลองใช้ปุ่มต่างๆ ทีละปุ่มในเครื่องมือทดสอบเกมแพด คุณจะพบว่าปุ่ม Assistant และ Capture ไม่ทำงาน แม้ว่าbuttons
แอตทริบิวต์ของเกมแพดตามที่กำหนดไว้ในข้อกำหนดของเกมแพดจะไม่มีขอบเขต แต่เนื่องจาก Stadia Controller ปรากฏเป็นเกมแพดมาตรฐาน ระบบจึงแมปเฉพาะปุ่ม 0-16 คุณยังคงใช้ปุ่มอื่นๆ ได้ แต่เกมส่วนใหญ่จะไม่คาดหวังว่าจะมีปุ่มเหล่านั้น
WebHID ช่วยได้
คุณสามารถพูดคุยกับปุ่มที่หายไป 17 และ 18 ได้ด้วย WebHID API และหากต้องการ คุณยังดูข้อมูลเกี่ยวกับปุ่มและแกนอื่นๆ ทั้งหมดที่มีอยู่แล้วผ่าน Gamepad API ได้ด้วย ขั้นตอนแรกคือการดูว่า Stadia Controller รายงานตัวเองต่อระบบปฏิบัติการอย่างไร วิธีหนึ่งในการทำเช่นนี้คือการเปิดคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ในหน้าใดก็ได้ แล้วขอรายการอุปกรณ์ที่ไม่มีการกรองจาก WebHID API จากนั้นคุณจะเลือก Stadia Controller ด้วยตนเองเพื่อตรวจสอบเพิ่มเติม รับรายการอุปกรณ์ที่ไม่มีการกรองโดยเพียงแค่ส่งfilters
อาร์เรย์ตัวเลือกที่ว่างเปล่า
const [device] = await navigator.hid.requestDevice({filters: []});
ในตัวเลือก รายการที่อยู่ก่อนสุดท้ายจะมีลักษณะเหมือน Stadia Controller
หลังจากเลือกอุปกรณ์ "Stadia Controller rev. A" แล้ว ให้บันทึกออบเจ็กต์ HIDDevice
ที่ได้ลงในคอนโซล ซึ่งจะแสดง productId
(37888
ซึ่งเป็น 0x9400
ในเลขฐานสิบหก) และ vendorId
(6353
ซึ่งเป็น 0x18d1
ในเลขฐานสิบหก) ของ Stadia Controller หากค้นหา vendorID
ในตารางรหัสผู้ให้บริการ USB อย่างเป็นทางการ คุณจะเห็นว่า 6353
แมปกับสิ่งที่คุณคาดไว้ นั่นคือ Google Inc.
อีกวิธีหนึ่งแทนที่จะทำตามขั้นตอนที่อธิบายไว้ข้างต้นคือไปที่ chrome://device-log/
ในแถบ URL กดปุ่มล้าง เสียบ Stadia Controller แล้วกดรีเฟรช ซึ่งจะให้ข้อมูลเดียวกันแก่คุณ
อีกทางเลือกหนึ่งคือการใช้เครื่องมือ HID Explorer ซึ่งช่วยให้คุณสำรวจรายละเอียดเพิ่มเติมของอุปกรณ์ HID ที่เชื่อมต่อกับคอมพิวเตอร์ได้
ใช้รหัสทั้ง 2 นี้ ได้แก่ vendorId
และ productId
เพื่อปรับแต่งสิ่งที่แสดงในเครื่องมือเลือกโดยการกรองอุปกรณ์ WebHID ที่ถูกต้อง
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
ตอนนี้เสียงรบกวนจากอุปกรณ์ที่ไม่เกี่ยวข้องทั้งหมดหายไปแล้ว และมีเพียง Stadia Controller เท่านั้นที่แสดงขึ้น
จากนั้นเปิด HIDDevice
โดยเรียกใช้เมธอด open()
await stadiaController.open();
บันทึก HIDDevice
อีกครั้ง และตั้งค่าสถานะ opened
เป็น true
เมื่ออุปกรณ์เปิดอยู่ ให้รอฟังเหตุการณ์ inputreport
ที่เข้ามาโดยแนบ Listener เหตุการณ์
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
เมื่อคุณกดและปล่อยปุ่ม Assistant บนตัวควบคุม ระบบจะบันทึกเหตุการณ์ 2 รายการลงใน Console คุณสามารถคิดว่าเหตุการณ์เหล่านี้เป็นเหตุการณ์ "กดปุ่ม Assistant" และ "ปล่อยปุ่ม Assistant" นอกเหนือจาก timeStamp
แล้ว เหตุการณ์ทั้ง 2 รายการนี้ดูไม่แตกต่างกันในตอนแรก
พร็อพเพอร์ตี้ reportId
ของอินเทอร์เฟซ HIDInputReportEvent
จะแสดงผลคำนำหน้าการระบุแบบ 1 ไบต์สำหรับรายงานนี้ หรือ 0
หากอินเทอร์เฟซ HID ไม่ได้ใช้รหัสรายงาน ในกรณีนี้คือ 3
โดยข้อมูลลับจะอยู่ในพร็อพเพอร์ตี้ data
ซึ่งแสดงเป็น DataView
ขนาด 10 DataView
มีอินเทอร์เฟซระดับต่ำสำหรับการอ่านและเขียนตัวเลขหลายประเภทในไบนารี ArrayBuffer
วิธีที่จะทำให้การแสดงข้อมูลนี้เข้าใจง่ายขึ้นคือการสร้าง Uint8Array
จาก ArrayBuffer
เพื่อให้คุณเห็นจำนวนเต็มแบบไม่มีเครื่องหมาย 8 บิตแต่ละรายการ
const data = new Uint8Array(event.data.buffer);
เมื่อคุณบันทึกข้อมูลเหตุการณ์รายงานอินพุตอีกครั้ง ทุกอย่างจะเริ่มสมเหตุสมผลมากขึ้น และเหตุการณ์ "ปุ่ม Assistant กดลง" และ "ปุ่ม Assistant ปล่อย" จะเริ่มถอดรหัสได้ จำนวนเต็มแรก (8
ในทั้ง 2 เหตุการณ์) ดูเหมือนจะเกี่ยวข้องกับการกดปุ่ม และจำนวนเต็มที่ 2 (2
และ 0
) ดูเหมือนจะเกี่ยวข้องกับการกดปุ่ม Assistant หรือไม่
กดปุ่มจับภาพแทนปุ่มผู้ช่วย แล้วคุณจะเห็นว่าจำนวนเต็มที่ 2 จะสลับจาก 1
เมื่อกดปุ่มเป็น 0
เมื่อปล่อยปุ่ม ซึ่งจะช่วยให้คุณเขียน "ไดรเวอร์" ที่เรียบง่ายมากซึ่งช่วยให้คุณใช้ปุ่มที่ขาดหายไป 2 ปุ่มได้
stadia.addEventListener('inputreport', (event) => {
if (!e.reportId === 3) {
return;
}
const data = new Uint8Array(event.data.buffer);
if (data[0] === 8) {
if (data[1] === 1) {
hidButtons[1].classList.add('highlight');
} else if (data[1] === 2) {
hidButtons[0].classList.add('highlight');
} else if (data[1] === 3) {
hidButtons[0].classList.add('highlight');
hidButtons[1].classList.add('highlight');
} else {
hidButtons[0].classList.remove('highlight');
hidButtons[1].classList.remove('highlight');
}
}
});
การใช้วิธีการย้อนกลับแบบนี้จะช่วยให้คุณทราบวิธีสื่อสารกับ Stadia Controller ด้วย WebHID ได้ทีละปุ่มและทีละแกน เมื่อเข้าใจแล้ว ที่เหลือก็เป็นเพียงการแมปจำนวนเต็มเชิงกล
สิ่งหนึ่งที่ขาดหายไปในตอนนี้คือประสบการณ์การเชื่อมต่อที่ราบรื่นซึ่ง Gamepad API มอบให้ แม้ว่าคุณจะต้องผ่านประสบการณ์การใช้ตัวเลือกเริ่มต้นอย่างน้อย 1 ครั้งเสมอเพื่อทำงานกับอุปกรณ์ WebHID เช่น Stadia Controller ด้วยเหตุผลด้านความปลอดภัย แต่สำหรับการเชื่อมต่อในอนาคต คุณสามารถเชื่อมต่อกับอุปกรณ์ที่รู้จักอีกครั้งได้ โดยการเรียกใช้เมธอด getDevices()
let stadiaController;
const [device] = await navigator.hid.getDevices();
if (device && device.vendorId === 6353 && device.productId === 37888) {
stadiaController = device;
}
สาธิต
คุณดู Stadia Controller ที่ควบคุมร่วมกันโดย Gamepad API และ WebHID API ได้ในการสาธิตที่ฉันสร้างขึ้น อย่าลืมดูซอร์สโค้ดซึ่งสร้างขึ้นจากข้อมูลโค้ดในบทความนี้ เพื่อความสะดวก ฉันจะแสดงเฉพาะปุ่ม A, B, X และ Y (ควบคุมโดย Gamepad API) รวมถึงปุ่มผู้ช่วยและจับภาพ (ควบคุมโดย WebHID API) คุณจะเห็นข้อมูล WebHID ดิบใต้รูปภาพของคอนโทรลเลอร์ ซึ่งจะช่วยให้คุณทราบถึงปุ่มและแกนทั้งหมดในคอนโทรลเลอร์
บทสรุป
เฟิร์มแวร์ใหม่ทำให้ตอนนี้คุณใช้ Stadia Controller เป็นเกมแพดมาตรฐานที่มีปุ่ม 17 ปุ่มได้แล้ว ซึ่งในกรณีส่วนใหญ่ก็เพียงพอต่อการควบคุมเกมบนเว็บทั่วไป หากคุณต้องการข้อมูลจากปุ่มทั้ง 19 ปุ่มบนคอนโทรลเลอร์ไม่ว่าจะด้วยเหตุผลใดก็ตาม WebHID จะช่วยให้คุณเข้าถึงรายงานอินพุตระดับต่ำได้ ซึ่งคุณสามารถถอดรหัสได้โดยการทำวิศวกรรมย้อนกลับทีละปุ่ม หากคุณเขียนไดรเวอร์ WebHID ที่สมบูรณ์หลังจากอ่านบทความนี้ โปรดติดต่อฉัน แล้วฉันจะลิงก์โปรเจ็กต์ของคุณที่นี่ ขอให้สนุกกับการใช้ WebHID
คำขอบคุณ
บทความนี้ได้รับการตรวจสอบโดย François Beaufort