WebHID üzerinden Stadia Kumanda ile konuşma

Yanıp sönen Stadia Kumanda, standart bir oyun kumandası gibi çalışır. Yani Oyun Kumandası API'si kullanılarak kumandanın tüm düğmelerine erişilemez. WebHID ile artık eksik düğmelere erişebilirsiniz.

Stadia kapandığından bu yana çoğu kişi kumandanın katı atık sahasında kullanışlı olmayan bir donanım olarak kalmasından korkuyordu. Neyse ki Stadia ekibi Stadia Kumanda'yı açmak için Stadia Bluetooth mode sayfasına giderek kumandanıza takabileceğiniz özel bir donanım yazılımı sağlamaya karar verdi. Böylece Stadia Kumanda, USB kablosu veya Bluetooth üzerinden kablosuz olarak bağlanabileceğiniz standart bir oyun kumandası olarak görünür. Project Fugu API'nin Vitrininde yer alan Stadia Bluetooth sayfasının kendisi WebHID ve WebUSB'yi kullanır ancak bu makalenin konusu bu değildir. Bu yayında, Stadia Kumanda ile WebHID üzerinden nasıl iletişim kurabileceğinizi açıklamak istiyorum.

Standart oyun kumandası olarak Stadia Kumanda

Kumanda, yanıp söndükten sonra işletim sistemi tarafından standart oyun kumandası olarak görünür. Standart bir oyun kumandası üzerinde ortak bir düğme ve eksen yerleşimi için aşağıdaki ekran görüntüsüne bakın. Oyun Kumandası API'si spesifikasyonunda tanımlandığı gibi standart oyun kumandalarında 0 ile 16 arasında düğmeler vardır, yani toplamda 17 düğme bulunur (d-pad dört düğme olarak sayılır). Oyun kumandası test kullanıcısı demosu üzerinde Stadia Kumanda'yı denerseniz çok iyi performans gösterdiğini göreceksiniz.

Çeşitli eksenler ve düğmelerin etiketlenmiş olduğu standart bir oyun kumandası şeması.

Ancak Stadia Kumanda'daki düğmelerin sayısı 19'dur. Bunları, oyun kumandası test cihazında sistematik olarak tek tek denerseniz, Asistan ve Yakalama düğmelerinin çalışmadığını fark edeceksiniz. Oyun kumandası buttons özelliği, Oyun Kumandası spesifikasyonunda tanımlandığı gibi açık uçlu olsa bile standart oyun kumandası olarak göründüğünden yalnızca 0-16 arasındaki düğmeler eşlenir. Diğer düğmeleri kullanmaya devam edebilirsiniz ancak çoğu oyunda düğme bulunmaz.

Kurtarıcı webHID

WebHID API sayesinde eksik olan 17 ve 18 düğmeleriyle konuşabilirsiniz. Ve gerçekten isterseniz Oyun Kumandası API'sı üzerinden zaten kullanılabilen diğer tüm düğmeler ve eksenler hakkında veri bile alabilirsiniz. İlk adım, Stadia Kumanda'nın kendisini işletim sistemine nasıl raporladığını öğrenmektir. Bunu yapmanın bir yolu, herhangi bir rastgele sayfada Chrome Geliştirici Araçları Konsolu'nu açmak ve WebHID API'den cihazların filtrelenmemiş bir listesini istemektir. Ardından daha ayrıntılı inceleme için Stadia Kumanda'yı manuel olarak seçersiniz. Filtrelenmemiş bir cihaz listesi elde etmek için boş bir filters seçenekleri dizisi iletmeniz yeterlidir.

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

Seçicide sondan bir önceki giriş Stadia Kumanda'ya benziyor.

İlgisiz cihazları gösteren WebHID API cihaz seçici ve sonda yer alan Stadia Kumanda.

"Stadia Kumanda rev. A" cihazını seçtikten sonra HIDDevice nesnesini konsola kaydedin. Bu şekilde, Stadia Kumanda'nın productId (37888, onaltılık 0x9400 cinsinden) ve vendorId (6353, onaltılık olarak 0x18d1) gösterilmektedir. Resmi USB tedarikçi firma kimliği tablosunda vendorID bilgisini ararsanız 6353, tam olarak beklediğinizle eşleşir: Google Inc..

HIDDevice nesnesinin günlük kaydı çıkışını gösteren Chrome Geliştirici Araçları Konsolu.

Yukarıda açıklanan akışa alternatif olarak URL çubuğunda chrome://device-log/ adresine gitmek, Temizle düğmesine basmak, Stadia Kumanda'nızı fişe takmak ve ardından Yenile'ye basmaktır. Bu işlem size aynı bilgileri sağlar.

Takılı Stadia Kumanda ile ilgili bilgileri gösteren chrome://device-log hata ayıklama arayüzü.

Bir diğer alternatif de bilgisayarınıza bağlı HID cihazları hakkında daha da fazla ayrıntıyı keşfetmenize olanak tanıyan HID Gezgini aracını kullanmaktır.

Artık doğru WebHID cihazı için doğru şekilde filtreleyerek seçicide gösterilenleri hassaslaştırmak üzere bu iki kimliği (vendorId ve productId) kullanın.

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

Artık alakasız cihazların tümündeki gürültü giderildi ve yalnızca Stadia Kumanda gösteriliyor.

Yalnızca Stadia Kumanda'yı gösteren WebHID API cihaz seçici.

Daha sonra, open() yöntemini çağırarak HIDDevice öğesini açın.

await stadiaController.open();

HIDDevice tekrar günlüğe kaydedilir ve opened işareti true olarak ayarlanır.

Chrome Geliştirici Araçları Konsolu, HIDDevice nesnesini açtıktan sonra günlüğe kaydetme işleminin sonucunu gösteren.

Cihaz açıkken bir etkinlik işleyici ekleyerek gelen inputreport etkinliklerini dinleyin.

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

Kumandadaki Asistan düğmesini bırakıp bıraktığınızda konsola iki etkinlik kaydedilir. Bunları "Asistan düğmesi aşağı" ve "Asistan düğmesi yukarı" etkinlikleri olarak düşünebilirsiniz. timeStamp dışında, iki etkinlik ilk bakışta ayırt edilemez görünüyor.

Chrome Geliştirici Araçları Konsolu, günlüğe kaydedilen HIDInputReportEvent nesnelerini gösteriyor.

HIDInputReportEvent arayüzünün reportId özelliği, bu rapor için bir baytlık tanımlama önekini veya HID arayüzü rapor kimliklerini kullanmıyorsa 0 değerini döndürür. Bu durumda, değer 3. Gizli anahtar, DataView boyutu 10 olarak gösterilen data özelliğinde bulunur. DataView, ArrayBuffer ikilisinde birden fazla sayı türünü okumak ve yazmak için düşük düzeyli bir arayüz sağlar. Bu gösterimden daha kolay anlaşılır bir şey elde etmenin yolu, ArrayBuffer üzerinden bir Uint8Array oluşturmaktır. Böylece, 8 bitlik imzalanmamış bağımsız tam sayıları görebilirsiniz.

const data = new Uint8Array(event.data.buffer);

Giriş raporu etkinlik verilerini tekrar günlüğe kaydettiğinizde, işler daha anlamlı hale gelir ve "Asistan düğmesi aşağıda" ve "Asistan düğmesi yukarı" etkinlikleri anlaşılır hale gelir. İlk tam sayı (her iki durumda da 8) tuşlara basmayla, ikinci tam sayı (2 ve 0) ise Asistan düğmesinin basılı olup olmamasıyla ilgili gibi görünüyor.

Chrome Geliştirici Araçları Konsolu, her HIDInputReportEvent için günlüğe kaydedilen Uint8Array nesnelerini gösteriyor.

Asistan düğmesi yerine Yakalama düğmesine bastığınızda, düğme serbest bırakıldığında 0 değerine basıldığında ikinci tam sayı 1 yerine geçer. Bu şekilde, eksik olan iki düğmeden yararlanmanıza olanak veren çok basit bir "sürücü" yazabilirsiniz.

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');
    }
  }
});

Bunun gibi bir tersine mühendislik yaklaşımı kullanarak webHID kullanarak Stadia Kumanda ile nasıl iletişim kuracağınızı öğrenebilirsiniz. İşi kavradıktan sonra geri kalan kısım, neredeyse mekanik tamsayı haritalama çalışmasına dönüşür.

Şu anda eksik olan tek şey, Gamepad API'sinin size sunduğu sorunsuz bağlantı deneyimidir. Güvenlik nedeniyle, Stadia Kumanda gibi bir WebHID cihazıyla çalışmak için her zaman ilk seçici deneyiminden geçmeniz gerekir. Bununla birlikte, gelecekteki bağlantılar için bilinen cihazlara yeniden bağlanabilirsiniz. Bunu, getDevices() yöntemini çağırarak yapabilirsiniz.

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

Demografi

Oluşturduğum bir demoda Stadia Kumanda'nın Gamepad API ile WebHID API tarafından birlikte kontrol edildiğini görebilirsiniz. Bu makaledeki snippet'leri temel alan kaynak koduna göz attığınızdan emin olun. Kolaylık olması için sadece A, B, X ve Y düğmelerini (Gamepad API tarafından kontrol edilir), Asistan ve Yakalama düğmelerini (WebHID API tarafından kontrol edilir) gösteriyorum. Denetleyici görüntüsünün altında ham WebHID verilerini görebilir, böylece kumandadaki tüm düğmeleri ve eksenleri görebilirsiniz.

Gamepad API'si ile kontrol edilen A, B, X ve Y düğmelerinin yanı sıra WebHID API tarafından kontrol edilen Asistan ve Yakalama düğmelerini gösteren https://stadia-controller-webhid-gamepad.glitch.me/ adresindeki demo uygulaması.

Sonuçlar

Yeni donanım yazılımı sayesinde Stadia Kumanda artık 17 düğmeli standart bir oyun kumandası olarak kullanılabiliyor. Bu da genelde yaygın web oyunlarını kontrol etmek için yeterli olan 17 düğmeli bir oyun kumandası. Herhangi bir nedenle kumandadaki 19 düğmenin tümünden verilere ihtiyacınız olursa WebHID, alt düzey giriş raporlarına erişmenizi sağlar. Bu raporlara, birer birer tersine mühendislik uygulayarak yorumlayabilirsiniz. Bu makaleyi okuduktan sonra eksiksiz bir WebHID sürücüsü yazarsanız bizimle iletişime geçmeyi unutmayın. Projenizin bağlantısını paylaşmaktan memnuniyet duyarım. WebHIDing'de başarılar!

Teşekkür

Bu makale François Beaufort tarafından incelenmiştir.