WebHID की मदद से Stadia कंट्रोलर से बात करना

फ़्लैश किया गया Stadia कंट्रोलर, एक स्टैंडर्ड गेमपैड की तरह काम करता है. इसका मतलब है कि इसके सभी बटन, Gamepad API के ज़रिए ऐक्सेस नहीं किए जा सकते. WebHID की मदद से, अब उन बटन को ऐक्सेस किया जा सकता है जो उपलब्ध नहीं हैं.

Stadia के बंद होने के बाद से, कई लोगों को डर था कि कचरे के मैदान में कंट्रोलर किसी बेकार हार्डवेयर की तरह काम नहीं करेगा. अच्छी बात यह है कि Stadia की टीम ने मनमुताबिक फ़र्मवेयर देकर Stadia कंट्रोलर खोलने का फ़ैसला लिया है. Stadia ब्लूटूथ मोड के पेज पर जाकर, इसे अपने कंट्रोलर पर फ़्लैश किया जा सकता है. इससे आपका Stadia कंट्रोलर, स्टैंडर्ड गेमपैड की तरह दिखेगा. इसे यूएसबी केबल या ब्लूटूथ की मदद से वायरलेस तरीके से कनेक्ट किया जा सकता है. Stadia ब्लूटूथ पेज को Project Fugu API शोकेस पर खास तौर पर दिखाया गया है. यह सुविधा अपने आप में WebHID और WebUSB का इस्तेमाल करती है, लेकिन यह इस लेख का विषय नहीं है. इस पोस्ट में, हम आपको बताना चाहते हैं कि WebHID की मदद से, Stadia कंट्रोलर से कैसे बात की जा सकती है.

स्टैंडर्ड गेमपैड की तरह Stadia कंट्रोलर

फ़्लैश होने के बाद, ऑपरेटिंग सिस्टम पर कंट्रोलर स्टैंडर्ड गेमपैड के तौर पर दिखता है. स्टैंडर्ड गेमपैड पर, सामान्य बटन और ऐक्सिस की व्यवस्था जानने के लिए, यह स्क्रीनशॉट देखें. जैसा कि Gamepad API के स्पेसिफ़िकेशन में बताया गया है, स्टैंडर्ड गेमपैड में 0 से 16 तक के बटन होते हैं. इसलिए, कुल 17 बटन होते हैं और डी-पैड को चार बटन के तौर पर गिना जाता है. अगर आप गेमपैड के टेस्टर डेमो पर Stadia कंट्रोलर का इस्तेमाल करते हैं, तो आपको दिखेगा कि यह किसी जादुई खेल की तरह काम करता है.

स्टैंडर्ड गेमपैड का स्कीमा, जिसमें अलग-अलग ऐक्सिस और बटन लेबल किए गए हैं.

हालांकि, अगर आप Stadia कंट्रोलर पर बटन गिनते हैं, तो आपको 19 बटन दिखेंगे. अगर गेमपैड टेस्टर में, इन ऐप्लिकेशन को एक-एक करके आज़माया जाता है, तो आपको पता चल जाएगा कि Assistant और कैप्चर करें बटन काम नहीं करेंगे. गेमपैड की खास जानकारी में बताए गए, गेमपैड buttons एट्रिब्यूट के ओपन-एंडेड होने पर भी, क्योंकि Stadia कंट्रोलर, स्टैंडर्ड गेमपैड की तरह दिखता है, लेकिन सिर्फ़ 0 से 16 बटन मैप किए जाते हैं. हालांकि, अब भी अन्य बटन इस्तेमाल किए जा सकते हैं. हालांकि, ज़्यादातर गेम में उनके मौजूद होने की उम्मीद नहीं की जाती.

बचाव के लिए WebHID

WebHID एपीआई की मदद से, ऐसे बटन 17 और 18 के बारे में बात की जा सकती है जो उपलब्ध नहीं हैं. अगर आप चाहें, तो Gamepad API के ज़रिए पहले से उपलब्ध अन्य सभी बटन और ऐक्सिस का डेटा भी हासिल किया जा सकता है. सबसे पहले, यह पता लगाना है कि Stadia कंट्रोलर, ऑपरेटिंग सिस्टम को कैसे रिपोर्ट करता है. इसका एक तरीका यह है कि किसी भी रैंडम पेज पर Chrome DevTools कंसोल खोलें. साथ ही, WebHID API से, बिना फ़िल्टर वाले डिवाइसों की सूची के लिए अनुरोध करें. इसके बाद, आगे की जांच के लिए, आप मैन्युअल तरीके से Stadia कंट्रोलर चुनें. आपको filters के विकल्पों का कलेक्शन खाली करके, डिवाइसों की बिना फ़िल्टर वाली सूची मिल जाएगी.

const [device] = await navigator.hid.requestDevice({filters: []});

पिकर में आखिरी एंट्री, Stadia कंट्रोलर की तरह दिखती है.

WebHID API डिवाइस पिकर, जिसमें डिवाइस से जुड़े हुए कुछ डिवाइस और Stadia कंट्रोलर को सबसे आखिरी स्थिति में दिखाया गया है.

"Stadia कंट्रोलर रेवेन्यू A" डिवाइस चुनने के बाद, मिलने वाले HIDDevice ऑब्जेक्ट को कंसोल में लॉग करें. इससे Stadia कंट्रोलर का productId (37888, जिसका हेक्स कोड 0x9400 होता है) और vendorId (6353, जो 0x18d1 हेक्स के तौर पर होता है) दिखता है. अगर आधिकारिक यूएसबी वेंडर आईडी टेबल में vendorID देखा जाता है, तो आपको 6353 से वही मैप दिखेगा जिसकी आपको उम्मीद है: Google Inc..

Chrome DevTools Console में एचआईडीडिवाइस ऑब्जेक्ट को लॉग करने का आउटपुट दिखाया गया है.

ऊपर बताए गए फ़्लो के अलावा, यूआरएल बार में chrome://device-log/ पर जाकर, मिटाएं बटन दबाएं, अपने Stadia कंट्रोलर को प्लग करें, और फिर रीफ़्रेश करें को दबाएं. इससे आपको वही जानकारी मिलेगी.

chrome://device-log डीबग इंटरफ़ेस, प्लग-इन किए गए Stadia कंट्रोलर के बारे में जानकारी दिखाता है.

इसके अलावा, एचआईडी एक्सप्लोरर टूल का इस्तेमाल भी किया जा सकता है. इसकी मदद से, अपने कंप्यूटर से कनेक्ट किए गए एचआईडी डिवाइसों के बारे में ज़्यादा जानकारी पाई जा सकती है.

पिकर में दिखाए जाने वाले कॉन्टेंट को बेहतर बनाने के लिए, vendorId और productId इन दो आईडी का इस्तेमाल करें. इसके लिए, अब सही WebHID डिवाइस को सही तरीके से फ़िल्टर करें.

const [stadiaController] = await navigator.hid.requestDevice({filters: [{
  vendorId: 6353,
  productId: 37888,
}]});

अब सभी मिलते-जुलते डिवाइसों का शोर खत्म हो गया है और सिर्फ़ Stadia कंट्रोलर दिखेगा.

WebHID API डिवाइस पिकर, जिसमें सिर्फ़ Stadia कंट्रोलर दिख रहा है.

इसके बाद, open() वाला तरीका कॉल करके HIDDevice खोलें.

await stadiaController.open();

HIDDevice को फिर से लॉग करें और opened फ़्लैग को true पर सेट कर दिया गया है.

Chrome DevTools कंसोल में, HIDDevice ऑब्जेक्ट को खोलने के बाद, उसे लॉग करने का आउटपुट दिखाया गया है.

डिवाइस खोलने के बाद, आने वाले inputreport इवेंट सुनने के लिए, इवेंट लिसनर को अटैच करें.

stadiaController.addEventListener('inputreport', (e) => {
  console.log(e);
});

जब आप कंट्रोलर पर Assistant बटन को दबाकर रखते हैं, तो कंसोल में दो इवेंट लॉग होते हैं. आपके हिसाब से, "Assistant बटन डाउन" और "Assistant बटन अप" वाले इवेंट को इवेंट के तौर पर गिना जा सकता है. timeStamp के अलावा, पहली नज़र में ये दोनों इवेंट अलग-अलग दिखते हैं.

Chrome DevTools कंसोल की इमेज, जिसमें HIDInputReportEvent ऑब्जेक्ट को लॉग किया जा रहा है.

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 बटन दबाया गया है या नहीं.

Chrome DevTools कंसोल की इमेज, जिसमें हर HIDInputReportEvent के लिए Uint8Array ऑब्जेक्ट को लॉग किया जा रहा है.

Assistant बटन के बजाय कैप्चर करें बटन दबाएं और आपको दिखेगा कि जब बटन रिलीज़ होने पर उसे 0 पर दबाया जाता है, तब 1 से दूसरा पूर्णांक टॉगल होता है. इससे आपको एक बहुत ही आसान "ड्राइवर" लिखने की सुविधा मिलती है, जिससे आप छूटे हुए दो बटनों का इस्तेमाल कर सकते हैं.

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 कंट्रोलर से कैसे बात की जाए. जब आप इसे समझ लें, तो बाकी काम करीब-करीब यांत्रिक पूर्णांक मैपिंग का ही हो जाता है.

एक चीज़ जो अब नहीं मिल रही है वह है, गेमपैड एपीआई से आसान कनेक्टिंग अनुभव. सुरक्षा से जुड़ी वजहों से, आपको Stadia कंट्रोलर जैसे WebHID डिवाइस के साथ काम करने के लिए, हमेशा एक बार शुरुआती पिकर अनुभव से गुज़रना होगा. आने वाले समय में कनेक्शन के लिए, अपने जाने-पहचाने डिवाइसों को फिर से कनेक्ट किया जा सकता है. ऐसा करने के लिए, getDevices() वाले तरीके को कॉल करें.

let stadiaController;
const [device] = await navigator.hid.getDevices();
if (device && device.vendorId === 6353 && device.productId === 37888) {
  stadiaController = device;
}

डेमो

आपने जो डेमो बनाया है उसमें Stadia कंट्रोलर को Gamepad API और WebHID API से कंट्रोल किया जा सकता है. सोर्स कोड देखना न भूलें, जो इस लेख के स्निपेट पर आधारित होता है. आसानी के लिए, सिर्फ़ A, B, X, और Y बटन (गेमपैड एपीआई से कंट्रोल किए जाते हैं) और Assistant और कैप्चर बटन (WebHID API से कंट्रोल किए जाते हैं) ही दिखाए जाते हैं. कंट्रोलर इमेज के नीचे, रॉ WebHID डेटा देखा जा सकता है, ताकि आपको कंट्रोलर पर मौजूद सभी बटन और ऐक्सिस का अंदाज़ा मिल सके.

https://stadia-controller-webhid-gamepad.glitch.me/ पर मौजूद डेमो ऐप्लिकेशन में A, B, X, और Y बटन दिखाए गए हैं, जिन्हें Gamepad API से कंट्रोल किया जा रहा है. साथ ही, WebHID API से कंट्रोल किए जा रहे Assistant और कैप्चर बटन को दिखाया गया है.

मीटिंग में सामने आए नतीजे

नए फ़र्मवेयर की वजह से, अब Stadia कंट्रोलर को 17 बटन वाले स्टैंडर्ड गेमपैड की तरह इस्तेमाल किया जा सकता है. ज़्यादातर मामलों में, यह सामान्य वेब गेम को कंट्रोल करने के लिए काफ़ी नहीं है. किसी भी वजह से, अगर आपको कंट्रोलर के सभी 19 बटन से डेटा चाहिए, तो WebHID आपको लो-लेवल की इनपुट रिपोर्ट का ऐक्सेस देता है. इन रिपोर्ट को एक-एक करके रिवर्स इंजीनियरिंग से समझा जा सकता है. अगर इस लेख को पढ़ने के बाद, आपने पूरा WebHID ड्राइवर लिखा है, तो मुझसे संपर्क करें. हमें आपके प्रोजेक्ट का लिंक यहां आसानी से दिया जाएगा. WebHIDing की शुभकामनाएं!

स्वीकार हैं

इस लेख की समीक्षा फ़्रैंसुआ ब्यूफ़ोर्ट ने की है.