Pengontrol Stadia yang di-flash berperilaku seperti gamepad standar, yang berarti tidak semua tombolnya dapat diakses menggunakan Gamepad API. Dengan WebHID, Anda kini dapat mengakses tombol yang hilang.
Sejak Stadia ditutup, banyak orang khawatir bahwa pengontrol akan berakhir sebagai perangkat keras yang tidak berguna di tempat pembuangan sampah. 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 Anda muncul sebagai gamepad standar yang dapat Anda hubungkan melalui kabel USB atau secara nirkabel melalui Bluetooth. Dengan bangga ditampilkan di Project Fugu API Showcase, halaman Bluetooth Stadia sendiri menggunakan WebHID dan WebUSB, tetapi bukan itu yang dibahas dalam artikel ini. Dalam postingan ini, saya ingin menjelaskan cara Anda dapat berbicara dengan pengontrol Stadia melalui WebHID.
Pengontrol Stadia sebagai gamepad standar
Setelah flashing, pengontrol akan muncul sebagai gamepad standar di sistem operasi. Lihat screenshot berikut untuk tata letak tombol dan sumbu umum pada gamepad standar. Seperti yang ditentukan dalam spesifikasi Gamepad API, gamepad standar memiliki tombol dari 0 hingga 16, jadi total 17 tombol (d-pad dihitung sebagai empat tombol). Jika Anda mencoba pengontrol Stadia di demo penguji gamepad, Anda akan melihat bahwa pengontrol tersebut berfungsi dengan baik.
Namun, jika Anda menghitung tombol di pengontrol Stadia, ada 19 tombol. Jika Anda mencobanya satu per satu secara sistematis di penguji gamepad, Anda akan menyadari bahwa tombol Asisten dan Ambil Gambar tidak berfungsi. Meskipun atribut buttons
gamepad seperti yang ditentukan dalam spesifikasi Gamepad bersifat terbuka, karena pengontrol Stadia muncul sebagai gamepad standar, hanya tombol 0–16 yang dipetakan. Anda tetap dapat menggunakan tombol lainnya, tetapi sebagian besar game tidak akan menganggapnya ada.
WebHID hadir untuk membantu
Berkat WebHID API, Anda dapat berinteraksi dengan tombol 17 dan 18 yang hilang. Jika Anda benar-benar ingin, Anda bahkan bisa mendapatkan data tentang semua tombol dan sumbu lain yang sudah tersedia melalui Gamepad API. Langkah pertama adalah mencari tahu cara pengontrol Stadia melaporkan dirinya ke sistem operasi. Salah satu caranya adalah dengan membuka Konsol Chrome DevTools di halaman acak, dan meminta daftar perangkat yang tidak difilter dari WebHID API. Kemudian, Anda memilih pengontrol Stadia secara manual untuk 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 kedua dari terakhir terlihat seperti pengontrol Stadia.
Setelah memilih perangkat "Stadia Controller rev. A", catat objek HIDDevice
yang dihasilkan ke Konsol. Hal ini akan menampilkan productId
(37888
, yang merupakan 0x9400
dalam hex) dan vendorId
(6353
, yang merupakan 0x18d1
dalam hex) pengontrol Stadia. Jika Anda mencari vendorID
di tabel ID vendor USB resmi, Anda akan menemukan bahwa 6353
dipetakan ke yang Anda harapkan: Google Inc.
.
Alternatif untuk alur yang dijelaskan di atas adalah membuka chrome://device-log/
di kolom URL, menekan tombol Hapus, mencolokkan pengontrol Stadia, lalu menekan Muat Ulang. Tindakan ini akan memberikan informasi yang sama kepada Anda.
Alternatif lainnya adalah menggunakan alat HID Explorer yang memungkinkan Anda menjelajahi lebih banyak detail perangkat HID yang terhubung ke komputer Anda.
Gunakan dua ID ini, vendorId
dan productId
, untuk menyempurnakan apa yang ditampilkan di pemilih dengan memfilter perangkat WebHID yang tepat dengan benar.
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
Sekarang, derau dari semua perangkat yang tidak terkait sudah hilang, dan hanya pengontrol Stadia yang muncul.
Selanjutnya, buka HIDDevice
dengan memanggil metode open()
.
await stadiaController.open();
Log HIDDevice
lagi, dan flag opened
ditetapkan ke true
.
Dengan perangkat terbuka, dengarkan peristiwa inputreport
yang masuk dengan melampirkan pemroses peristiwa.
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
Saat Anda menekan dan melepaskan tombol Asisten di pengontrol, dua peristiwa dicatat ke Konsol. Anda dapat menganggapnya sebagai peristiwa "tombol Asisten ditekan" dan "tombol Asisten dilepas". Selain timeStamp
, kedua peristiwa tersebut terlihat tidak dapat dibedakan pada pandangan pertama.
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, nilainya adalah 3
. Secret ada di properti data
, yang ditampilkan 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 bilangan bulat 8-bit yang tidak bertanda.
const data = new Uint8Array(event.data.buffer);
Saat Anda mencatat data peristiwa laporan input lagi, semuanya akan mulai lebih masuk akal dan peristiwa "tombol Asisten ditekan" dan "tombol Asisten dilepas" akan mulai dapat dipahami. Integer pertama (8
di kedua peristiwa) tampaknya terkait dengan penekanan tombol, dan integer kedua (2
dan 0
) tampaknya terkait dengan apakah tombol Asisten ditekan atau tidak.
Tekan tombol Ambil, bukan tombol Asisten, dan Anda akan melihat bahwa bilangan bulat kedua beralih dari 1
saat tombol ditekan ke 0
saat tombol dilepaskan. Dengan begitu, Anda dapat menulis "driver" yang sangat sederhana untuk menggunakan dua tombol yang tidak ada.
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 menggunakan pendekatan rekayasa balik seperti ini, Anda dapat, tombol demi tombol dan sumbu demi sumbu, mengetahui cara berkomunikasi dengan pengontrol Stadia menggunakan WebHID. Setelah Anda menguasainya, sisanya adalah pekerjaan pemetaan bilangan bulat yang hampir mekanis.
Satu hal yang kini hilang adalah pengalaman koneksi lancar yang diberikan Gamepad API kepada Anda. Meskipun karena alasan keamanan Anda harus selalu melalui pengalaman pemilih awal satu kali untuk bekerja dengan perangkat WebHID seperti pengontrol Stadia, untuk koneksi mendatang, Anda dapat menghubungkan kembali ke perangkat yang dikenal. Lakukan hal itu 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 dalam demo yang telah saya buat. Pastikan untuk melihat kode sumber, yang dibuat berdasarkan cuplikan dari artikel ini. Demi kesederhanaan, saya hanya menampilkan tombol A, B, X, dan Y (dikontrol oleh Gamepad API), serta tombol Asisten dan Ambil (dikontrol oleh WebHID API). Di bawah gambar pengontrol, Anda dapat melihat data WebHID mentah, sehingga Anda dapat merasakan semua tombol dan sumbu pada pengontrol.
Kesimpulan
Berkat firmware baru, pengontrol Stadia kini dapat digunakan sebagai gamepad standar dengan 17 tombol, yang dalam sebagian besar kasus, sudah lebih dari cukup untuk mengontrol game web umum. Jika karena alasan apa pun Anda memerlukan data dari semua 19 tombol di pengontrol, WebHID memungkinkan Anda mendapatkan akses ke laporan input tingkat rendah yang dapat Anda dekode dengan merekayasa baliknya satu per satu. Jika Anda menulis driver WebHID lengkap setelah membaca artikel ini, pastikan untuk menghubungi saya, dan saya akan dengan senang hati menautkan project Anda di sini. Selamat menggunakan WebHID!
Ucapan terima kasih
Artikel ini ditinjau oleh François Beaufort.