Stadia Controller ที่แฟลชจะทํางานเหมือนเกมแพดมาตรฐาน ซึ่งหมายความว่าปุ่มบางปุ่มจะเข้าถึงไม่ได้โดยใช้ Gamepad API ตอนนี้คุณเข้าถึงปุ่มที่หายไปได้แล้วด้วย WebHID
เมื่อ Stadia ปิดตัวลง หลายคนกลัวว่าตัวควบคุมจะกลายเป็นฮาร์ดแวร์ไร้ประโยชน์ที่กองขยะ แต่โชคดีที่ทีม Stadia ตัดสินใจที่จะเปิด Stadia Controller แทนโดยให้เฟิร์มแวร์ที่กำหนดเองซึ่งคุณสามารถแฟลชลงในตัวควบคุมได้โดยไปที่หน้าโหมดบลูทูธของ Stadia ซึ่งจะทำให้ Stadia Controller ปรากฏเป็นเกมแพดมาตรฐานที่คุณสามารถเชื่อมต่อผ่านสาย USB หรือแบบไร้สายผ่านบลูทูธ หน้า Stadia Bluetooth แสดงอยู่ใน 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: []});
ในเครื่องมือเลือก รายการที่ 2 สุดท้ายจะมีลักษณะคล้ายกับ Stadia Controller
หลังจากเลือกอุปกรณ์ "Stadia Controller rev. A" แล้ว ให้บันทึกออบเจ็กต์ HIDDevice
ที่แสดงในคอนโซล ซึ่งจะแสดง productId
(37888
ซึ่งก็คือ 0x9400
ในฐาน 16) และ vendorId
(6353
ซึ่งก็คือ 0x18d1
ในฐาน 16) ของ Stadia Controller หากค้นหา vendorID
ในตารางรหัสผู้ให้บริการ USB อย่างเป็นทางการ คุณจะเห็น 6353
แมปกับสิ่งที่คุณคาดไว้ ซึ่งก็คือ Google Inc.
อีกวิธีหนึ่งนอกเหนือจากขั้นตอนที่อธิบายข้างต้นคือการไปที่ chrome://device-log/
ในแถบ URL, กดปุ่มล้าง, เสียบ Stadia Controller แล้วกดรีเฟรช ซึ่งจะให้ข้อมูลเดียวกันกับคุณ
อีกทางเลือกหนึ่งคือการใช้เครื่องมือ HID Explorer ซึ่งให้คุณสำรวจรายละเอียดเพิ่มเติมของอุปกรณ์ HID ที่เชื่อมต่อกับคอมพิวเตอร์
ใช้รหัส vendorId
และ productId
2 รหัสนี้เพื่อปรับแต่งสิ่งที่แสดงในเครื่องมือเลือกโดยกรองหาอุปกรณ์ WebHID ที่ถูกต้อง
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
ตอนนี้สัญญาณรบกวนจากอุปกรณ์ที่ไม่เกี่ยวข้องทั้งหมดจะหายไป และมีเพียง Stadia Controller เท่านั้นที่แสดง
ถัดไป ให้เปิด HIDDevice
โดยการเรียกใช้เมธอด open()
await stadiaController.open();
บันทึก HIDDevice
อีกครั้ง แล้วตั้งค่า Flag opened
เป็น true
เมื่อเปิดอุปกรณ์ ให้รอฟังเหตุการณ์ inputreport
ที่เข้ามาโดยแนบ Listener เหตุการณ์
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
เมื่อคุณกดปุ่ม Assistant บนตัวควบคุมแล้วปล่อย ระบบจะบันทึกเหตุการณ์ 2 รายการลงในคอนโซล คุณสามารถมองเหตุการณ์เหล่านี้เป็นเหตุการณ์ "ปุ่ม 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
และ 0
) ดูเหมือนจะเกี่ยวข้องกับการกดปุ่ม Assistant หรือไม่
กดปุ่มจับภาพแทนปุ่ม 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) รวมถึงปุ่ม Assistant และ Capture (ควบคุมโดย WebHID API) เพื่อความสะดวก คุณจะเห็นข้อมูล WebHID ดิบใต้รูปภาพตัวควบคุม เพื่อให้ทราบถึงปุ่มและแกนทั้งหมดบนตัวควบคุม
สรุป
เฟิร์มแวร์ใหม่นี้ช่วยให้ Stadia Controller ใช้เป็นเกมแพดมาตรฐานที่มีปุ่ม 17 ปุ่มได้ ซึ่งในกรณีส่วนใหญ่แล้วถือว่าเพียงพอที่จะควบคุมเกมบนเว็บทั่วไป หากต้องการข้อมูลจากปุ่มทั้ง 19 ปุ่มบนตัวควบคุมไม่ว่าด้วยเหตุผลใดก็ตาม WebHID จะช่วยให้คุณเข้าถึงรายงานอินพุตระดับต่ำซึ่งคุณสามารถถอดรหัสได้โดยการทำวิศวกรรมย้อนกลับทีละรายการ หากคุณเขียนโปรแกรมควบคุมอุปกรณ์ WebHID ที่สมบูรณ์หลังจากอ่านบทความนี้ โปรดติดต่อเราและเรายินดีที่จะลิงก์โปรเจ็กต์ของคุณที่นี่ ขอให้สนุกกับ WebHID
ขอขอบคุณ
บทความนี้ผ่านการตรวจสอบโดย François Beaufort