בקר Stadia המעודכן פועל כמו גיימפאד רגיל, כלומר לא ניתן לגשת לכל הלחצנים שלו באמצעות Gamepad API. בעזרת WebHID, עכשיו יש לכם גישה ללחצנים החסרים.
מאז שהשירות של Stadia נסגר, רבים חששו שהשלט הרחוק יהפוך לחתיכת חומרה חסרת תועלת בזבל. למרבה המזל, צוות Stadia החליט לפתוח את השלט הרחוק ל-Stadia במקום זאת, על ידי מתן קושחת בהתאמה אישית שאפשר להטמיע בשלט. כדי לעשות זאת, עוברים לדף מצב Bluetooth של Stadia. כך השלט הרחוק ל-Stadia יופיע כגאמפאד רגיל שאפשר לחבר באמצעות כבל USB או באופן אלחוטי באמצעות Bluetooth. הדף של Stadia Bluetooth, שמוצג בגאווה ב-Project Fugu API Showcase, משתמש ב-WebHID וב-WebUSB, אבל זה לא הנושא של המאמר הזה. בפוסט הזה אסביר איך אפשר לתקשר עם השלט הרחוק של Stadia דרך WebHID.
השלט הרחוק ל-Stadia כגיימפאד רגיל
אחרי העדכון, הבקרים מופיעים כגאימפאד סטנדרטי במערכת ההפעלה. בצילום המסך הבא אפשר לראות סידור נפוץ של לחצנים ואקסים במשטח משחק רגיל. כפי שמוגדר במפרט של Gamepad API, לבקרים רגילים יש לחצנים מ-0 עד 16, כלומר 17 בסך הכול (לוח הלחצנים נספר כארבע לחצנים). אם תנסו את שלט Stadia בדמו של בודק הגיימפאד, תבחינו שהוא עובד מצוין.
עם זאת, אם סופרים את הלחצנים בשלט הרחוק ל-Stadia, יש 19. אם תבדקו אותם באופן שיטתי אחד אחרי השני בבודק של השלט, תגלו שהלחצנים Assistant ו-Capture לא פועלים. גם אם המאפיין buttons
של בקר המשחקים, כפי שהוא מוגדר במפרט של בקר המשחקים, הוא פתוח, מאחר שבקר Stadia מופיע כבקרת משחקים רגילה, רק הלחצנים 0 עד 16 ממופים. עדיין תוכלו להשתמש בלחצנים האחרים, אבל רוב המשחקים לא ייצפו לקיומם.
WebHID מציל את המצב
בזכות WebHID API, אפשר לדבר עם הלחצנים החסרים 17 ו-18. אם אתם רוצים, אתם יכולים אפילו לקבל נתונים על כל הלחצנים והצירים האחרים שכבר זמינים דרך Gamepad API. השלב הראשון הוא לבדוק איך השלט הרחוק של Stadia מדווח על עצמו למערכת ההפעלה. אחת מהדרכים לעשות זאת היא לפתוח את מסוף כלי הפיתוח של Chrome בדף אקראי כלשהו, ולבקש רשימה של מכשירים ללא סינון מ-WebHID API. לאחר מכן, בוחרים באופן ידני את השלט הרחוק ל-Stadia לבדיקה נוספת. כדי לקבל רשימה לא מסוננת של מכשירים, פשוט מעבירים מערך אפשרויות filters
ריק.
const [device] = await navigator.hid.requestDevice({filters: []});
בבורר, הערך שלפני האחרון נראה כמו השלט הרחוק של Stadia.
אחרי שבוחרים את המכשיר 'Stadia Controller rev. A', מתעדים ביומן את האובייקט HIDDevice
שנוצר במסוף. כך תוכלו לראות את הערכים של productId
(37888
, שהוא 0x9400
בחזקת 16) ושל vendorId
(6353
, שהוא 0x18d1
בחזקת 16) בשלט הרחוק של Stadia. אם מחפשים את הערך vendorID
בטבלה הרשמית של מזהי ספקי USB, רואים ש-6353
ממופה למה שציפיתם: Google Inc.
.
חלופה לתהליך שמתואר למעלה היא לנווט אל chrome://device-log/
בסרגל כתובות ה-URL, ללחוץ על הלחצן ניקוי, לחבר את השליט של Stadia וללחוץ על רענון. כך תוכלו לקבל את אותו המידע.
אפשרות נוספת היא להשתמש בכלי HID Explorer, שמאפשר לקבל פרטים נוספים על מכשירי ה-HID שמחוברים למחשב.
משתמשים בשני המזהים האלה, vendorId
ו-productId
, כדי לסנן בצורה נכונה את מכשיר WebHID הנכון ולשפר את מה שמוצג בבורר.
const [stadiaController] = await navigator.hid.requestDevice({filters: [{
vendorId: 6353,
productId: 37888,
}]});
עכשיו הרעש מכל המכשירים הלא קשורים נעלם, ורק השלט של Stadia מופיע.
בשלב הבא, פותחים את HIDDevice
באמצעות קריאה ל-method open()
.
await stadiaController.open();
מתעדים שוב את HIDDevice
, והדגל opened
מוגדר לערך true
.
כשהמכשיר פתוח, אפשר לצרף רכיב מעקב אירועים כדי להאזין לאירועי inputreport
נכנסים.
stadiaController.addEventListener('inputreport', (e) => {
console.log(e);
});
כשלוחצים על הלחצן Assistant בשלט הרחוק ומשחררים אותו, שני אירועים נרשמים ביומן במסוף. אפשר לחשוב עליהם כאירועים של 'לחיצה על לחצן ההפעלה של Assistant' ו'לחיצה על לחצן ההשבתה של Assistant'. מלבד הערך timeStamp
, קשה להבחין בין שני האירועים במבט ראשון.
המאפיין reportId
בממשק HIDInputReportEvent
מחזיר את הקידומת המזהה באורך ביייט אחד של הדוח הזה, או את הערך 0
אם בממשק ה-HID לא נעשה שימוש במזהי דוחות. במקרה הזה, 3
. הסוד נמצא במאפיין data
, שמיוצג כ-DataView
בגודל 10. DataView
מספק ממשק ברמה נמוכה לקריאה ולכתיבה של מספר סוגי מספרים ב-ArrayBuffer
בינארי. כדי ליצור ייצוג קל יותר לעיכול, אפשר ליצור Uint8Array
מ-ArrayBuffer
, כך שתוכלו לראות את המספרים השלמים הלא חתומים של 8 ביט.
const data = new Uint8Array(event.data.buffer);
כשרושמים שוב ביומן את נתוני האירועים בדוח הקלט, הדברים מתחילים להיראות הגיוניים יותר, וקל יותר לפענח את האירועים 'לחיצה על הלחצן של Assistant למטה' ו'לחיצה על הלחצן של Assistant למעלה'. נראה שהמספר השלם הראשון (8
בשני האירועים) קשור ללחיצות על לחצנים, והמספר השלם השני (2
ו-0
) קשור לכך שהלחצן של Assistant נלחץ או לא.
לוחצים על הלחצן צילום במקום על הלחצן Assistant, ותראו שהמספר השלם השני עובר מ-1
כשהלחצן לוחצים עליו ל-0
כשמשחררים אותו. כך תוכלו לכתוב 'דרייבר' פשוט מאוד שמאפשר לכם להשתמש בשני הלחצנים החסרים.
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');
}
}
});
באמצעות גישה כזו של הנדסת הפוך, אפשר להבין איך לדבר עם בקר Stadia באמצעות WebHID, כפתור אחר כפתור וציר אחר ציר. אחרי שמבינים את העיקרון, שאר התהליך הוא כמעט מכני.
הדבר היחיד שעוד חסר הוא חוויית החיבור החלקה שמקבלים מ-Gamepad API. מטעמי אבטחה, תמיד צריך לעבור את תהליך הבחירה הראשוני פעם אחת כדי לעבוד עם מכשיר WebHID כמו בקר Stadia. עם זאת, לחיבורים עתידיים, אפשר לחבר מחדש מכשירים מוכרים. כדי לעשות זאת, צריך להפעיל את method getDevices()
.
let stadiaController;
const [device] = await navigator.hid.getDevices();
if (device && device.vendorId === 6353 && device.productId === 37888) {
stadiaController = device;
}
הדגמה (דמו)
אפשר לראות את השליטה המשותפת של Gamepad API ו-WebHID API ב-Stadia controller בדמו שיצרתי. מומלץ לעיין בקוד המקור, שמבוסס על קטעי הקוד במאמר הזה. כדי לפשט את העניין, אני מציג רק את הלחצנים A, B, X ו-Y (שנשלטים על ידי Gamepad API), ואת הלחצנים Assistant ו-Capture (שנשלטים על ידי WebHID API). מתחת לתמונה של הבקר מוצגים נתוני WebHID גולמיים, כדי שתוכלו להבין איך פועלים כל הלחצנים והצירים בבקר.
מסקנות
הודות לקושחה החדשה, עכשיו אפשר להשתמש בשלט Stadia כגאמפאד רגיל עם 17 לחצנים, שמספיק ברוב המקרים כדי לשלוט במשחקי אינטרנט נפוצים. אם מסיבה כלשהי אתם צריכים נתונים מכל 19 הלחצנים ב-controller, WebHID מאפשר לכם לקבל גישה לדוחות קלט ברמה נמוכה, שתוכלו לפענח באמצעות הנדסה לאחור שלהם אחד אחרי השני. אם כתבתם מנהל התקן WebHID מלא אחרי קריאת המאמר הזה, אל תשכחו ליצור איתי קשר ואשמח לקשר את הפרויקט שלכם כאן. שימוש מהנה ב-WebHID!
תודות
המאמר הזה נבדק על ידי François Beaufort.