फ़्लैश किया गया Stadia कंट्रोलर, स्टैंडर्ड गेमपैड की तरह काम करता है. इसका मतलब है कि इसके सभी बटन, Gamepad API का इस्तेमाल करके ऐक्सेस नहीं किए जा सकते. WebHID की मदद से, अब उन बटन को ऐक्सेस किया जा सकता है जो मौजूद नहीं हैं.
Stadia बंद होने के बाद, कई लोगों को डर था कि कंट्रोलर, लैंडफ़िल में बेकार हार्डवेयर के तौर पर खत्म हो जाएगा. अच्छी बात यह है कि Stadia की टीम ने Stadia कंट्रोलर को ओपन करने का फ़ैसला किया है. इसके लिए, टीम ने कस्टम फ़र्मवेयर उपलब्ध कराया है. इसे अपने कंट्रोलर पर फ़्लैश किया जा सकता है. इसके लिए, आपको Stadia कंट्रोलर के ब्लूटूथ मोड वाले पेज पर जाना होगा. इससे आपका Stadia कंट्रोलर, एक स्टैंडर्ड गेमपैड के तौर पर दिखता है. इसे यूएसबी केबल या ब्लूटूथ के ज़रिए वायरलेस तरीके से कनेक्ट किया जा सकता है. Stadia का ब्लूटूथ पेज, WebHID और WebUSB का इस्तेमाल करता है. इसे Project Fugu API Showcase में भी दिखाया गया है. हालांकि, इस लेख में इन एपीआई के बारे में नहीं बताया गया है. इस पोस्ट में, हम आपको WebHID के ज़रिए Stadia कंट्रोलर से बात करने का तरीका बताएंगे.
Stadia कंट्रोलर को स्टैंडर्ड गेमपैड के तौर पर इस्तेमाल करना
फ़्लैश होने के बाद, कंट्रोलर ऑपरेटिंग सिस्टम को स्टैंडर्ड गेमपैड के तौर पर दिखता है. स्टैंडर्ड गेमपैड पर मौजूद सामान्य बटन और ऐक्सिस के लेआउट के लिए, यहां दिया गया स्क्रीनशॉट देखें. Gamepad API के ब्यौरे के मुताबिक, स्टैंडर्ड गेमपैड में 0 से 16 तक के बटन होते हैं. इसलिए, कुल 17 बटन होते हैं. डी-पैड को चार बटन के तौर पर गिना जाता है. अगर आपने गेमपैड टेस्टर डेमो पर Stadia कंट्रोलर आज़माया है, तो आपको पता होगा कि यह बहुत अच्छी तरह से काम करता है.
हालांकि, Stadia कंट्रोलर पर मौजूद बटन की संख्या 19 है. अगर आप गेमपैड टेस्टर में एक-एक करके इन बटन को आज़माते हैं, तो आपको पता चलेगा कि Assistant और Capture बटन काम नहीं करते. गेमपैड के स्पेसिफ़िकेशन में बताए गए buttons
एट्रिब्यूट की वैल्यू चाहे जो भी हो, Stadia कंट्रोलर को स्टैंडर्ड गेमपैड के तौर पर दिखाया जाता है. इसलिए, सिर्फ़ बटन 0–16 मैप किए जाते हैं. आपके पास अब भी अन्य बटन इस्तेमाल करने का विकल्प है, लेकिन ज़्यादातर गेम में इन बटन के काम करने की उम्मीद नहीं की जाती.
WebHID API की मदद से समस्या हल करना
WebHID API की मदद से, बटन 17 और 18 से कम्यूनिकेट किया जा सकता है. अगर आपको चाहिए, तो Gamepad API के ज़रिए पहले से उपलब्ध सभी बटन और ऐक्सिस के बारे में भी डेटा पाया जा सकता है. पहला चरण यह पता लगाना है कि Stadia कंट्रोलर, ऑपरेटिंग सिस्टम को खुद के बारे में जानकारी कैसे देता है. इसके लिए, किसी भी पेज पर Chrome DevTools कंसोल खोलें. इसके बाद, WebHID API से डिवाइसों की ऐसी सूची का अनुरोध करें जिसमें कोई फ़िल्टर न लगा हो. इसके बाद, जांच के लिए Stadia कंट्रोलर को मैन्युअल तरीके से चुना जाता है. सिर्फ़ खाली filters
options array पास करके, डिवाइसों की बिना फ़िल्टर की गई सूची पाएं.
const [device] = await navigator.hid.requestDevice({filters: []});
पिकर में, दूसरी आखिरी एंट्री Stadia कंट्रोलर की तरह दिखती है.
"Stadia Controller rev. A" डिवाइस चुनने के बाद, Console में HIDDevice
ऑब्जेक्ट को लॉग करें. इससे Stadia कंट्रोलर का productId
(37888
, जो हेक्स में 0x9400
है) और vendorId
(6353
, जो हेक्स में 0x18d1
है) दिखता है. अगर यूएसबी वेंडर आईडी की आधिकारिक टेबल में vendorID
को खोजा जाता है, तो आपको पता चलेगा कि 6353
, आपकी उम्मीद के मुताबिक Google Inc.
से मैप होता है.
ऊपर बताए गए तरीके के अलावा, chrome://device-log/
पर जाकर भी ऐसा किया जा सकता है. इसके लिए, यूआरएल बार में chrome://device-log/
पर जाएं. इसके बाद, मिटाएं बटन दबाएं. अब Stadia कंट्रोलर को प्लग इन करें और फिर रीफ़्रेश करें बटन दबाएं. इससे आपको वही जानकारी मिलती है.
इसके अलावा, एचआईडी एक्सप्लोरर टूल का इस्तेमाल करके भी एचआईडी डिवाइसों के बारे में ज़्यादा जानकारी पाई जा सकती है. यह टूल, आपके कंप्यूटर से कनेक्ट किए गए एचआईडी डिवाइसों के बारे में ज़्यादा जानकारी देता है.
इन दो आईडी, vendorId
और productId
का इस्तेमाल करके, पिकर में दिखने वाले आइटम को बेहतर बनाया जा सकता है. इसके लिए, सही WebHID डिवाइस को फ़िल्टर किया जा सकता है.
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
अब इससे जुड़े सभी डिवाइसों से आने वाली आवाज़ बंद हो गई है और सिर्फ़ Stadia कंट्रोलर की आवाज़ सुनाई दे रही है.
इसके बाद, open()
तरीके को कॉल करके HIDDevice
खोलें.
await stadiaController.open();
HIDDevice
को फिर से लॉग करें. इसके बाद, opened
फ़्लैग को true
पर सेट किया जाता है.
डिवाइस चालू होने पर, इवेंट लिसनर अटैच करके, आने वाले inputreport
इवेंट सुनें.
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
कंट्रोलर पर Assistant बटन को दबाकर छोड़ने पर, Console में दो इवेंट लॉग किए जाते हैं. इन्हें "Assistant बटन दबाया गया" और "Assistant बटन छोड़ा गया" इवेंट के तौर पर देखा जा सकता है. timeStamp
को छोड़कर, दोनों इवेंट पहली नज़र में एक जैसे दिखते हैं.
HIDInputReportEvent
इंटरफ़ेस की reportId
प्रॉपर्टी, इस रिपोर्ट के लिए एक बाइट का आइडेंटिफ़िकेशन प्रीफ़िक्स दिखाती है. अगर एचआईडी इंटरफ़ेस रिपोर्ट आईडी का इस्तेमाल नहीं करता है, तो यह 0
दिखाती है. इस मामले में, यह 3
है. सीक्रेट, data
प्रॉपर्टी में होता है. इसे 10 साइज़ के DataView
के तौर पर दिखाया जाता है. DataView
, बाइनरी ArrayBuffer
में कई नंबर टाइप को पढ़ने और लिखने के लिए, लो-लेवल इंटरफ़ेस उपलब्ध कराता है. इस प्रज़ेंटेशन से ज़्यादा जानकारी पाने के लिए, ArrayBuffer
से Uint8Array
बनाएं, ताकि आपको अलग-अलग 8-बिट अनसाइंड इंटिजर दिख सकें.
const data = new Uint8Array(event.data.buffer);
इसके बाद, जब इनपुट रिपोर्ट इवेंट डेटा को फिर से लॉग किया जाता है, तो चीज़ें ज़्यादा समझ में आने लगती हैं. साथ ही, "Assistant बटन दबाया गया" और "Assistant बटन छोड़ा गया" इवेंट को समझा जा सकता है. पहली पूर्णांक संख्या (दोनों इवेंट में 8
) बटन दबाने से जुड़ी है. वहीं, दूसरी पूर्णांक संख्या (2
और 0
) इस बात से जुड़ी है कि Assistant बटन दबाया गया है या नहीं.
Assistant बटन के बजाय कैप्चर करें बटन दबाएं. आपको दिखेगा कि बटन दबाने पर दूसरा पूर्णांक 1
से 0
पर टॉगल होता है. इससे आपको एक बहुत ही आसान "ड्राइवर" लिखने की सुविधा मिलती है. इसकी मदद से, दो बटन का इस्तेमाल किया जा सकता है.
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');
}
}
});
इस तरह के रिवर्स-इंजीनियरिंग के तरीके का इस्तेमाल करके, बटन दर बटन और ऐक्सिस दर ऐक्सिस, यह पता लगाया जा सकता है कि WebHID की मदद से Stadia कंट्रोलर से कैसे बात की जाए. एक बार जब आपको इसकी आदत पड़ जाएगी, तो बाकी काम सिर्फ़ पूर्णांकों को मैप करने का होगा.
हालांकि, अब भी एक चीज़ की कमी है. वह है गेमपैड एपीआई की मदद से मिलने वाला बेहतरीन कनेक्टिविटी अनुभव. सुरक्षा की वजहों से, आपको WebHID डिवाइस (जैसे, Stadia कंट्रोलर) के साथ काम करने के लिए, पहली बार डिवाइस चुनने की प्रोसेस पूरी करनी होगी. हालाँकि, आने वाले समय में कनेक्ट करने के लिए, पहले से कनेक्ट किए गए डिवाइसों से दोबारा कनेक्ट किया जा सकता है. इसके लिए, getDevices()
तरीके को कॉल करें.
let stadiaController;
const [device] = await navigator.hid.getDevices();
if (device && device.vendorId === 6353 && device.productId === 37888) {
stadiaController = device;
}
डेमो
मैंने एक डेमो बनाया है. इसमें, Gamepad API और WebHID API, दोनों से कंट्रोल किए जा रहे Stadia कंट्रोलर को देखा जा सकता है. इस लेख में दिए गए स्निपेट के आधार पर बनाए गए सोर्स कोड को ज़रूर देखें. आसानी से समझने के लिए, मैंने सिर्फ़ A, B, X, और Y बटन (जिन्हें Gamepad API कंट्रोल करता है) और Assistant और Capture बटन (जिन्हें WebHID API कंट्रोल करता है) दिखाए हैं. कंट्रोलर की इमेज के नीचे, आपको WebHID का रॉ डेटा दिखेगा. इससे आपको कंट्रोलर के सभी बटन और ऐक्सिस के बारे में जानकारी मिलेगी.
मीटिंग में सामने आए नतीजे
नए फ़र्मवेयर की मदद से, Stadia कंट्रोलर को अब 17 बटन वाले स्टैंडर्ड गेमपैड के तौर पर इस्तेमाल किया जा सकता है. ज़्यादातर मामलों में, सामान्य वेब गेम को कंट्रोल करने के लिए यह काफ़ी है. अगर आपको किसी भी वजह से कंट्रोलर के सभी 19 बटन का डेटा चाहिए, तो WebHID की मदद से, इनपुट की लो-लेवल रिपोर्ट ऐक्सेस की जा सकती हैं. इन रिपोर्ट को एक-एक करके रिवर्स-इंजीनियरिंग करके समझा जा सकता है. अगर आपने इस लेख को पढ़ने के बाद, पूरा WebHID ड्राइवर लिखा है, तो हमसे संपर्क करना न भूलें. हमें आपके प्रोजेक्ट को यहां लिंक करने में खुशी होगी. WebHID का इस्तेमाल करने के लिए शुभकामनाएं!
Acknowledgements
इस लेख की समीक्षा फ़्रांस्वा बोफ़ोर्ट ने की है.