Pengontrol Stadia yang di-flash berfungsi seperti gamepad standar, yang berarti tidak semua tombolnya dapat diakses menggunakan Gamepad API. Dengan WebHID, Anda kini dapat mengakses tombol yang hilang.
Sejak Stadia dihentikan, banyak yang khawatir pengontrolnya akan berubah menjadi hardware yang tidak berguna di TPA. Untungnya, tim Stadia telah memutuskan untuk membuka pengontrol Stadia dengan menyediakan firmware kustom yang dapat Anda flash di pengontrol dengan membuka halaman mode Bluetooth Stadia. Hal ini membuat pengontrol Stadia tampak sebagai gamepad standar yang dapat dihubungkan melalui kabel USB atau secara nirkabel melalui Bluetooth. Dengan bangga ditampilkan di Etalase Project Fugu API, halaman Bluetooth Stadia sendiri menggunakan WebHID dan WebUSB, tetapi ini bukan topik dalam artikel ini. Dalam postingan ini, saya ingin menjelaskan cara berkomunikasi dengan pengontrol Stadia melalui WebHID.
Pengontrol Stadia sebagai gamepad standar
Setelah berkedip, pengontrol akan muncul sebagai gamepad standar ke sistem operasi. Lihat screenshot berikut untuk mengetahui pengaturan sumbu dan tombol yang umum pada gamepad standar. Seperti yang didefinisikan dalam spesifikasi Gamepad API, gamepad standar memiliki tombol dari 0 hingga 16, jadi totalnya adalah 17 (d-pad dihitung sebagai empat tombol). Jika mencoba pengontrol Stadia pada demo penguji gamepad, Anda akan melihat bahwa pengontrol ini berfungsi seperti charm.
Namun, kalau kamu menghitung tombol-tombol di pengontrol Stadia, ada 19. Jika Anda mencobanya satu per satu secara sistematis di penguji gamepad, Anda akan menyadari bahwa tombol Assistant dan Capture tidak berfungsi. Meskipun atribut buttons
gamepad seperti yang didefinisikan dalam spesifikasi Gamepad bersifat open-ended, karena pengontrol Stadia muncul sebagai gamepad standar, hanya tombol 0–16 yang dipetakan. Anda tetap dapat menggunakan tombol lain, tetapi sebagian besar game tidak akan mengharapkan tombol tersebut ada.
WebHID siap membantu
Berkat WebHID API, Anda dapat berkomunikasi dengan tombol 17 dan 18 yang tidak ada. Jika menginginkannya, Anda bahkan bisa mendapatkan data tentang semua tombol dan sumbu lainnya yang sudah tersedia melalui Gamepad API. Langkah pertama adalah mencari tahu bagaimana pengontrol Stadia melaporkan dirinya sendiri ke sistem operasi. Salah satu cara untuk melakukannya adalah dengan membuka Konsol Chrome DevTools di halaman acak, dan meminta daftar perangkat yang tidak difilter dari WebHID API. Kemudian, pilih pengontrol Stadia secara manual untuk melakukan pemeriksaan lebih lanjut. Dapatkan daftar perangkat yang tidak difilter hanya dengan meneruskan array opsi filters
yang kosong.
const [device] = await navigator.hid.requestDevice({filters: []});
Di pemilih, entri dari belakang terlihat seperti pengontrol Stadia.
Setelah memilih perangkat "Stadia Controller rev. A", catat objek HIDDevice
yang dihasilkan ke Konsol. Tindakan ini mengungkapkan productId
pengontrol Stadia (37888
, yang berupa 0x9400
dalam hex) dan vendorId
(6353
, yaitu 0x18d1
dalam hex). Jika mencari vendorID
di tabel ID vendor USB resmi, Anda akan menemukan bahwa 6353
dipetakan sesuai dengan yang Anda harapkan: Google Inc.
.
Alternatif untuk alur yang dijelaskan di atas adalah membuka chrome://device-log/
di kolom URL, menekan tombol Clear, mencolokkan pengontrol Stadia, lalu menekan Refresh. Dengan begitu, Anda akan mendapatkan informasi yang sama.
Alternatif lainnya adalah menggunakan alat Penjelajah HID yang memungkinkan Anda menjelajahi detail selengkapnya tentang perangkat HID yang terhubung ke komputer Anda.
Gunakan kedua ID ini, vendorId
dan productId
, untuk mempertajam informasi yang ditampilkan di alat pilih dengan kini memfilter perangkat WebHID yang tepat dengan benar.
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
Sekarang suara dari semua perangkat yang tidak terkait akan hilang, dan hanya pengontrol Stadia yang muncul.
Selanjutnya, buka HIDDevice
dengan memanggil metode open()
.
await stadiaController.open();
Catat HIDDevice
lagi, dan flag opened
disetel ke true
.
Saat perangkat terbuka, proses peristiwa inputreport
yang masuk dengan menambahkan pemroses peristiwa.
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
Saat Anda menekan dan melepaskan tombol Assistant pada pengontrol, dua peristiwa akan dicatat ke Konsol. Anda bisa menganggapnya sebagai peristiwa "Assistant tombol bawah" dan "Asisten button up". Selain timeStamp
, kedua peristiwa ini terlihat tidak dapat dibedakan secara sekilas.
Properti reportId
dari antarmuka HIDInputReportEvent
menampilkan awalan identifikasi satu byte untuk laporan ini, atau 0
jika antarmuka HID tidak menggunakan ID laporan. Dalam hal ini, parameternya adalah 3
. Rahasia ini ada di properti data
, yang direpresentasikan sebagai DataView
berukuran 10. DataView
menyediakan antarmuka tingkat rendah untuk membaca dan menulis beberapa jenis angka dalam ArrayBuffer
biner. Cara untuk mendapatkan sesuatu yang lebih mudah dipahami dari representasi ini adalah dengan membuat Uint8Array
dari ArrayBuffer
, sehingga Anda dapat melihat masing-masing bilangan bulat 8-bit yang tidak ditandatangani.
const data = new Uint8Array(event.data.buffer);
Saat Anda kemudian mencatat data peristiwa laporan input lagi ke dalam log, semuanya akan menjadi lebih masuk akal dan peristiwa "Asisten tombol turun" dan "tombol Asisten" mulai dapat dipahami. Bilangan bulat pertama (8
di kedua peristiwa) tampaknya terkait dengan penekanan tombol, dan bilangan bulat kedua (2
dan 0
) tampaknya terkait dengan apakah tombol Assistant ditekan atau tidak.
Tekan tombol Capture sebagai ganti tombol Assistant, dan Anda akan melihat bahwa bilangan bulat kedua beralih dari 1
saat tombol ditekan ke 0
saat dirilis. Hal ini memungkinkan Anda menulis "driver" yang sangat sederhana yang memungkinkan Anda memanfaatkan dua tombol yang hilang.
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');
}
}
});
Dengan pendekatan rekayasa balik seperti ini, Anda dapat menentukan tombol demi tombol dan sumbu demi sumbu, untuk mencari tahu cara berkomunikasi dengan pengontrol Stadia dengan WebHID. Setelah Anda memahaminya, sisanya adalah pekerjaan pemetaan bilangan bulat mekanis.
Satu hal yang tidak ada sekarang adalah pengalaman menghubungkan yang lancar yang diberikan Gamepad API kepada Anda. Meskipun untuk alasan keamanan, Anda harus selalu menggunakan pengalaman pemilih awal satu kali untuk dapat menggunakan perangkat WebHID seperti pengontrol Stadia. Untuk koneksi mendatang, Anda dapat terhubung kembali ke perangkat yang dikenal. Lakukan hal tersebut dengan memanggil metode getDevices()
.
let stadiaController;
const [device] = await navigator.hid.getDevices();
if (device && device.vendorId === 6353 && device.productId === 37888) {
stadiaController = device;
}
Demo
Anda dapat melihat pengontrol Stadia yang dikontrol bersama oleh Gamepad API dan WebHID API di demo yang telah saya buat. Pastikan untuk memeriksa kode sumber, yang dibuat berdasarkan cuplikan dari artikel ini. Agar lebih praktis, saya hanya menampilkan tombol A, B, X, dan Y (dikontrol oleh Gamepad API), serta tombol Assistant dan Capture (dikontrol oleh WebHID API). Di bawah gambar pengontrol, Anda dapat melihat data WebHID mentah, sehingga Anda dapat memahami semua tombol dan sumbu pada pengontrol.
Kesimpulan
Berkat firmware baru, pengontrol Stadia kini dapat digunakan sebagai gamepad standar dengan 17 tombol, yang pada umumnya lebih dari cukup untuk mengontrol game web umum. Jika, karena alasan apa pun, Anda memerlukan data dari ke-19 tombol pada pengontrol, WebHID memungkinkan Anda mendapatkan akses ke laporan input tingkat rendah yang dapat Anda pahami dengan merekayasa baliknya satu per satu. Jika Anda kebetulan menulis driver WebHID lengkap setelah membaca artikel ini, pastikan untuk menghubungi saya, dan saya akan dengan senang hati menautkan proyek Anda di sini. Selamat menggunakan WebHIDing!
Ucapan terima kasih
Artikel ini ditinjau oleh François Beaufort.