Yanıp sönen Stadia kumanda, standart bir oyun kumandası gibi çalışır. Bu nedenle, Gamepad API'si kullanılarak düğmelerinin tümüne erişilemez. WebHID ile artık eksik düğmelere erişebilirsiniz.
Stadia'nın kapatılmasından sonra birçok kişi, kumandanın çöp sahasında işe yaramaz bir donanım parçası olarak son bulacağından korkuyordu. 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'nın kilidini açmaya karar verdi. Bu işlem, Stadia Kumanda'nızı USB kablosuyla veya Bluetooth üzerinden kablosuz olarak bağlayabileceğiniz standart bir oyun kumandası olarak gösterir. Project Fugu API Showcase'ta yer alan Stadia Bluetooth sayfası WebHID ve WebUSB kullanıyor ancak bu makalenin konusu bu değil. Bu yayında, WebHID üzerinden Stadia kumandasıyla nasıl iletişim kurabileceğinizi açıklamak istiyorum.
Standart oyun kumandası olarak Stadia Kumanda
Yanıp sönme işleminden sonra, kontrol cihazı işletim sistemine standart bir gamepad olarak görünür. Standart bir gamepad'deki yaygın düğme ve eksen düzenlemesi için aşağıdaki ekran görüntüsüne bakın. Gamepad API spesifikasyonunda belirtildiği gibi, standart gamepad'lerde 0 ila 16 arasında düğme bulunur. Yani toplamda 17 düğme vardır (d-pad dört düğme olarak sayılır). Stadia Kumanda'yı oyun kumandası test cihazı demosunda denerseniz kusursuz çalıştığını göreceksiniz.
Ancak Stadia kumandadaki düğmeleri sayarsanız 19 tane olduğunu görürsünüz. Oyun kumandası test cihazında düğmeleri tek tek sistematik bir şekilde denerseniz Asistan ve Kayıt düğmelerinin çalışmadığını fark edersiniz. Oyun kumandası spesifikasyonunda tanımlanan oyun kumandası buttons
özelliği açık uçlu olsa bile Stadia kumanda standart bir oyun kumandası olarak göründüğü için 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'in yardımı
WebHID API sayesinde, eksik 17 ve 18 numaralı düğmelerle iletişim kurabilirsiniz. Gerçekten isterseniz Gamepad API üzerinden zaten mevcut olan diğer tüm düğmeler ve eksenler hakkında veri de alabilirsiniz. İlk adım, Stadia kumandasının kendisini işletim sistemine nasıl bildirdiğini bulmaktır. Bunu yapmanın bir yolu, herhangi bir sayfada Chrome Geliştirici Araçları Konsolu'nu açıp WebHID API'den filtrelenmemiş bir cihaz listesi istemektir. Daha ayrıntılı inceleme için Stadia kumandasını manuel olarak seçin. Boş bir filters
seçenek dizisi ileterek filtrelenmemiş bir cihaz listesi alın.
const [device] = await navigator.hid.requestDevice({filters: []});
Seçicide, sondan bir önceki giriş Stadia kumandasına benzer.
"Stadia Kumanda rev. A" cihazını seçtikten sonra, ortaya çıkan HIDDevice
nesnesini Console'a kaydedin. Bu işlem, Stadia kumandasının productId
(37888
, onaltılık sistemde 0x9400
) ve vendorId
(6353
, onaltılık sistemde 0x18d1
) değerlerini gösterir. Resmi USB tedarikçi firma kimliği tablosunda vendorID
değerini ararsanız 6353
değerinin beklediğinizle eşleştiğini görürsünüz: Google Inc.
.
Yukarıda açıklanan akışa alternatif olarak, URL çubuğunda chrome://device-log/
simgesine gidip Temizle düğmesine basabilir, Stadia kumandanızı takabilir ve ardından Yenile'ye basabilirsiniz. Bu sayede aynı bilgileri elde edebilirsiniz.
Bilgisayarınıza bağlı HID cihazlarla ilgili daha fazla ayrıntıyı keşfetmenize olanak tanıyan HID Explorer aracını da kullanabilirsiniz.
Seçicide gösterilenleri hassaslaştırmak için bu iki kimliği (vendorId
ve productId
) kullanarak doğru WebHID cihazını doğru şekilde filtreleyin.
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
Artık alakasız tüm cihazlardan gelen gürültü ortadan kalktı ve yalnızca Stadia kumanda gösteriliyor.
Ardından, open()
yöntemini çağırarak HIDDevice
öğesini açın.
await stadiaController.open();
HIDDevice
öğesini tekrar kaydedin. opened
işareti true
olarak ayarlanır.
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üğmesi aşağı" ve "Asistan düğmesi yukarı" etkinlikleri olarak düşünebilirsiniz. timeStamp
dışında, iki etkinlik ilk bakışta birbirinden ayırt edilemez.
HIDInputReportEvent
arayüzünün reportId
mülkü, bu rapor için bir baytlık tanımlama ön ekini veya HID arayüzü rapor kimlikleri kullanmıyorsa 0
değerini döndürür. Bu durumda 3
olur. Gizli anahtar, 10 boyutunda bir DataView
olarak temsil edilen data
mülkünde bulunur. 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 temsilden daha kolay anlaşılır bir şey elde etmenin yolu, ArrayBuffer
'tan bir Uint8Array
oluşturmaktır. Böylece, 8 bitlik imzasız tam sayıları tek tek görebilirsiniz.
const data = new Uint8Array(event.data.buffer);
Ardından giriş raporu etkinlik verilerini tekrar günlüğe kaydettiğinizde işler daha anlamlı hale gelmeye başlar ve "Asistan düğmesi aşağı" ve "Asistan düğmesi yukarı" etkinlikleri anlaşılır hale gelir. İlk tam sayı (her iki etkinlikte de 8
), düğmeye basmalarla ilgilidir. İkinci tam sayı (2
ve 0
) ise Asistan düğmesine basılı olup olmadığıyla ilgilidir.
Asistan düğmesi yerine Yakalama düğmesine basın. İkinci tam sayının, düğmeye basıldığında 1
değerinden, düğme bırakıldığında 0
değerine geçtiğini görürsünüz. Bu sayede, eksik iki düğmeyi kullanmanıza olanak tanıyan ç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 tür bir tersine mühendislik yaklaşımı kullanarak, düğme düğme ve eksen eksen, WebHID ile Stadia kumandasıyla nasıl iletişim kuracağınızı anlayabilirsiniz. Bu konuyu anladıktan sonra geri kalanı neredeyse mekanik bir tam sayı eşleme çalışmasıdır.
Şimdilik eksik olan tek şey, Gamepad API'nin sunduğu sorunsuz bağlantı deneyimi. Stadia Kumanda gibi bir WebHID cihazıyla çalışmak için güvenlik nedeniyle her zaman ilk seçici deneyimini bir kez yaşamanız gerekir. Ancak sonraki 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;
}
Demo
Hazırladığım demo'da, Gamepad API ve WebHID API tarafından ortaklaşa kontrol edilen Stadia kumandasını görebilirsiniz. Bu makaledeki snippet'leri temel alan kaynak koda göz atın. Basitlik açısından yalnızca A, B, X ve Y düğmelerini (Gamepad API tarafından kontrol edilir) ve Asistan ile Kayıt düğmelerini (WebHID API tarafından kontrol edilir) göstereceğiz. Denetleyici resminin altında, ham WebHID verilerini görebilirsiniz. Böylece, denetleyicideki tüm düğmeleri ve eksenleri anlayabilirsiniz.
Sonuçlar
Yeni donanım yazılımı sayesinde Stadia Kumanda artık 17 düğmeli standart bir oyun kumandası olarak kullanılabilir. Bu, çoğu durumda yaygın web oyunlarını kontrol etmek için fazlasıyla yeterlidir. Herhangi bir nedenle kumandadaki 19 düğmenin tümünün verilerine ihtiyacınız varsa WebHID, düşük düzey giriş raporlarına erişmenize olanak tanır. Bu raporları tek tek tersine mühendislik yaparak çözebilirsiniz. Bu makaleyi okuduktan sonra eksiksiz bir WebHID sürücüsü yazarsanız benimle iletişime geçmeyi unutmayın. Projenizi buradan memnuniyetle bağlayacağım. Web'de gizlilik için iyi günler dileriz.
Teşekkür ederiz
Bu makale François Beaufort tarafından incelenmiştir.