WebHID üzerinden Stadia Kumanda ile konuşma

Flaşlı Stadia Kumanda, standart bir oyun kumandası gibi davranır. Bu nedenle, Gamepad API kullanılarak tüm düğmelerine erişilemez. WebHID ile artık eksik düğmelere erişebilirsiniz.

Stadia'nın kapatılmasının ardından birçok kişi, kumandanın çöplükte işe yaramaz bir donanım parçası olarak kalacağından endişelendi. Neyse ki Stadia ekibi, Stadia Bluetooth modu sayfasına giderek kumandanıza yükleyebileceğiniz özel bir donanım yazılımı sağlayarak Stadia Kumanda'yı açmaya karar verdi. Bu sayede Stadia Kumanda'nız, USB kablosuyla veya Bluetooth üzerinden kablosuz olarak bağlanabileceğiniz standart bir oyun kumandası gibi görünür. Project Fugu API Showcase'de öne çıkarılan Stadia Bluetooth sayfası, WebHID ve WebUSB kullanır ancak bu makalenin konusu bu değildir. Bu yayında, WebHID aracılığıyla Stadia Kumanda ile nasıl konuşabileceğinizi açıklamak istiyorum.

Stadia Kumanda'yı standart bir oyun kumandası olarak kullanma

Flaşlama işleminden sonra kumanda, işletim sisteminde standart bir gamepad olarak görünür. Standart bir gamepad'deki yaygın düğme ve eksen düzeni için aşağıdaki ekran görüntüsüne bakın. Gamepad API spesifikasyonunda tanımlandığı gibi, standart gamepad'lerde 0 ile 16 arasında numaralandırılmış toplam 17 düğme bulunur (yön tuşları dört düğme olarak sayılır). Stadia Kumanda'yı oyun kumandası test cihazı demosunda denerseniz sorunsuz bir şekilde çalıştığını görürsünüz.

Çeşitli eksenlerin ve düğmelerin etiketlendiği standart bir gamepad şeması.

Ancak Stadia Kumanda'daki düğmeleri sayarsanız 19 düğme olduğunu görürsünüz. Oyun kumandası test cihazında bunları sistematik olarak tek tek denerseniz Asistan ve Yakalama düğmelerinin çalışmadığını fark edersiniz. Oyun kumandası spesifikasyonunda tanımlanan buttons özelliği açık uçlu olsa bile Stadia Kumanda standart bir 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 bu düğmelerin varlığı beklenmez.

WebHID imdada yetişiyor

WebHID API sayesinde eksik düğmeler 17 ve 18 ile iletişim kurabilirsiniz. İsterseniz Gamepad API'si aracılığıyla kullanılabilen diğer tüm düğmeler ve eksenler hakkında da veri alabilirsiniz. İlk adım, Stadia Kumanda'nın işletim sistemine nasıl bildirildiğini öğrenmektir. Bunu yapmanın bir yolu, rastgele bir sayfada Chrome Geliştirici Araçları Konsolu'nu açmak ve WebHID API'den filtrelenmemiş bir cihaz listesi istemektir. Ardından, daha ayrıntılı inceleme için Stadia Kumanda'yı manuel olarak seçersiniz. Boş bir filters seçenekler dizisi ileterek cihazların filtrelenmemiş bir listesini alın.

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

Seçicideki sondan bir önceki giriş, Stadia Kumanda'ya benzer.

WebHID API cihaz seçicisi, bazı alakasız cihazları ve sondan bir önceki konumda Stadia Kumanda'yı gösteriyor.

"Stadia Controller rev. A" cihazını seçtikten sonra, ortaya çıkan HIDDevice nesnesini Console'a kaydedin. Bu işlem, Stadia Kumanda'nın productId (37888, onaltılık sistemde 0x9400) ve vendorId (6353, onaltılık sistemde 0x18d1) değerlerini gösterir. Resmi USB satıcı kimliği tablosunda vendorID değerini aradığınızda 6353 değerinin beklediğiniz gibi Google Inc. ile eşlendiğini görürsünüz.

HIDDevice nesnesinin günlüğe kaydedilmesinin çıktısını gösteren Chrome Geliştirici Araçları Konsolu.

Yukarıda açıklanan akışa alternatif olarak URL çubuğunda chrome://device-log/ simgesine gidip Temizle düğmesine basabilir, Stadia Kumanda'nızı takabilir ve ardından Yenile'ye basabilirsiniz. Bu işlem, aynı bilgileri sağlar.

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

Bir diğer alternatif ise bilgisayarınıza bağlı HID cihazlarının daha da fazla ayrıntısını keşfetmenize olanak tanıyan HID Explorer aracını kullanmaktır.

Doğru WebHID cihazı için doğru şekilde filtreleme yaparak 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 tüm cihazlardan gelen gürültü yok ve yalnızca Stadia Kumanda görünüyor.

WebHID API cihaz seçicisinde yalnızca Stadia Kumanda gösteriliyor.

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

await stadiaController.open();

HIDDevice tekrar kaydedilir ve opened işareti true olarak ayarlanır.

Açıldıktan sonra HIDDevice nesnesinin kaydedilmesinin çıktısını gösteren Chrome Geliştirici Araçları Konsolu.

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

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

Kumandadaki Asistan düğmesine basıp bıraktığınızda Console'a iki etkinlik kaydedilir. Bunları "Asistan düğmesine basma" ve "Asistan düğmesini bırakma" etkinlikleri olarak düşünebilirsiniz. timeStamp dışında, iki etkinlik ilk bakışta ayırt edilemez.

HIDInputReportEvent nesnelerinin kaydedildiğini gösteren Chrome Geliştirici Araçları Konsolu.

reportId arayüzünün HIDInputReportEvent özelliği, bu rapor için bir baytlık tanımlama önekini veya HID arayüzü rapor kimlikleri kullanmıyorsa 0 değerini döndürür. Bu örnekte 3. Gizli anahtar, 10 boyutunda bir DataView olarak gösterilen data özelliğindedir. DataView, ikili ArrayBuffer içinde birden fazla sayı türünü okumak ve yazmak için düşük düzeyli bir arayüz sağlar. Bu gösterimden daha anlaşılır bir sonuç elde etmenin yolu, ArrayBuffer'den Uint8Array oluşturmaktır. Böylece bağımsız 8 bitlik işaretsiz tam sayıları görebilirsiniz.

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

Ardından giriş raporu etkinlik verilerini tekrar kaydettiğinizde işler daha anlamlı hale gelir ve "Asistan düğmesi aşağı" ile "Asistan düğmesi yukarı" etkinlikleri anlaşılır olmaya başlar. İlk tam sayı (her iki etkinlikte de 8), düğmeye basma işlemleriyle, ikinci tam sayı (2 ve 0) ise Asistan düğmesine basılıp basılmadığıyla ilgili görünüyor.

Her bir HIDInputReportEvent için Uint8Array nesnelerinin kaydedildiğini gösteren Chrome Geliştirici Araçları Konsolu.

Asistan düğmesi yerine Yakalama düğmesine basın. Düğmeye basıldığında ikinci tam sayının 1'den 0'ye değiştiğini görürsünüz. Bu sayede, eksik iki düğmeyi kullanmanızı sağlayan ç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');
    }
  }
});

Bu gibi bir tersine mühendislik yaklaşımı kullanarak düğme düğme ve eksen eksen WebHID ile Stadia Kumanda ile nasıl iletişim kuracağınızı anlayabilirsiniz. Bu işin mantığını kavradıktan sonra geri kalan kısım neredeyse mekanik bir tam sayı eşleme çalışmasıdır.

Şu anda eksik olan tek şey, Gamepad API'nin sunduğu sorunsuz bağlantı deneyimi. Güvenlik nedeniyle, Stadia Kumanda gibi bir WebHID cihazıyla çalışmak için ilk seçici deneyimini her zaman bir kez yaşamanız gerekir. Ancak gelecekteki bağlantılar için bilinen cihazlara yeniden bağlanabilirsiniz. Bunu getDevices() yöntemini çağırarak yapın.

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

Demo

Oluşturduğum demoda, Gamepad API ve WebHID API tarafından ortaklaşa kontrol edilen Stadia kumandasını görebilirsiniz. Bu makaledeki snippet'lerden yararlanılarak oluşturulan kaynak koduna göz atmayı unutmayın. Basitlik adına yalnızca A, B, X ve Y düğmelerini (Gamepad API tarafından kontrol edilir) ve Asistan ile Kaydet düğmelerini (WebHID API tarafından kontrol edilir) gösteriyorum. Denetleyici resminin altında, ham WebHID verilerini görebilirsiniz. Böylece, denetleyicideki tüm düğmeler ve eksenler hakkında fikir edinebilirsiniz.

Oyun Kumandası API'si tarafından kontrol edilen A, B, X ve Y düğmelerinin, WebHID API'si tarafından kontrol edilen Asistan ve Kaydet düğmelerinin gösterildiği Stadia Kumanda 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 düğme sayısı, çoğu durumda yaygın web oyunlarını kontrol etmek için yeterli oluyor. Herhangi bir nedenle kumandadaki 19 düğmenin tamamından veri almanız gerekiyorsa WebHID, tersine mühendislik yaparak tek tek çözebileceğiniz düşük seviyeli giriş raporlarına erişmenize olanak tanır. Bu makaleyi okuduktan sonra eksiksiz bir WebHID sürücüsü yazarsanız benimle iletişime geçmeyi unutmayın. Projenizi buraya eklemekten memnuniyet duyarım. WebHID'yi keyifle kullanın.

Teşekkür

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