MAME360'a save state ve favoriler ekledikten sonra bu kez kontrolcü meselesine geçtim. Elimdeki Hori Fighting Stick mini 4'ü Xbox 360'ta, özellikle de MAME'de kullanmak istiyordum.
Sonunda PlayStation Classic kolunu, bir USB çevirici üzerinden PS1/PS2 kollarını ve Hori'yi çalıştırdım. Orijinal DualShock 3'ü de USB kabloyla denedim. HidDriver360 V1.0 release altında şu anda hepsi çalışıyor. Bu noktaya gelene kadar kernel adresleri, XEX yükleme sorunları, USB raporları ve cihazın bağlantının ortasında kimlik değiştirmesiyle uğraştım.
Derlemeleri Windows'ta yaptım; Xbox denemelerini de gerçekleştirdim. Süreç çoğunlukla yeni bir XEX derlemek, konsola taşımak, sonucu görmek ve logu geri getirip PC'de incelemek şeklinde geçti.
Başlangıç: HidDriver360
Temel aldığım proje EinTim23/hiddriver360 oldu:
https://github.com/EinTim23/hiddriver360
Mevcut HidDriver360'ın kontrolcü okuma, eşleme ve Xbox'a sanal kontrolcü olarak sunma altyapısı üzerinden ilerledim. Başlangıç noktası v0.6-beta kaynaklarıydı.
Temel commit:
d42173a7e4d2eb967d1cc092d77638f42a40f246
Benim konsolun DashLaunch'ta görünen bilgileri şöyleydi:
Board: Jasper
Flash: Jasper
Type: Glitch
Kernel: 2.0.17511.0
Projenin başlangıçtaki desteklediği sistemler arasında 17559 retail ve 17489 devkit vardı. Bendeki 17511 için doğrudan çalışan bir uyarlama yoktu. Konsolun sistemini güncellemek yerine sürücüyü mevcut sisteme uydurmak istedim.
PlayStation Classic ile gelen ve PS1 koluna benzeyen Sony USB kontrolcüsünü Windows, Linux, RetroPie ve Android gibi farklı ortamlarda kullanmıştım. Bu yüzden ilk beklentim generic bir yapıda olduğunu düşündüğüm bu donanımın Xbox'ta da benzer şekilde çalışmasıydı.
Fakat USB bağlantısı ile işletim sisteminin o cihazı oyun kolu olarak kabul etmesi ayrı konular. HID bir kolun tuşlarını, yönlerini ve analoglarını diğerinden farklı bir rapor yapısında gönderebiliyor. Bazı cihazlar ise bağlantı sırasında bambaşka bir USB arayüzüne geçebiliyor. Hori'de gördüğüm bu oldu.
O yüzden bu forku “USB kolları takınca çalışan evrensel sürücü” olarak tanımlayamıyorum maalesef. Ortak bir altyapı var ama denediğim cihazların eşlemesi, başlatma davranışı ve gerektiğinde paket biçiminin ayrıca ele alınması gerekti.
İlk deneme: plugin kayıtlı, fakat hiçbir tepki yok
İlk olarak indirdiğim XEX'i Xbox'ın diskine attım, DashLaunch'ta plugin olarak kaydettim ve konsolu tamamen kapatıp açtım. Plugin satırının kaydedildiğini de tekrar kontrol ettim.
Aurora'da Hori'yi söküp taktım; yönlere ve tuşlara bastım. MAME'de de denedim. Hiçbir tepki yoktu. Bazı denemelerde log bile oluşmuyordu.
Burada ilk ayrım şuydu: DashLaunch'ta dosya yolunun kayıtlı olması, sürücünün başarıyla yüklendiğini veya kontrolcüyü çalıştırdığını kanıtlamıyor. Önce yükleme zincirini görünür hale getirmek gerekiyordu.
DVD tepsisinin bununla ne ilgisi var?
Bu sırada beklemediğim bir ayrıntı çıktı: sürücüde tepsi açıkken devreye girmemeyi sağlayan bir kontrol vardı. Benim konsolda DVD sürücüsü bulunmadığı için sistemin tepsiyi nasıl gördüğünü de kontrol ettim.
Original dashboard'daki ikondan optik sürücünün kapalı olduğunu görmekle yetinmedim ve teşhis uygulamasının SMC'den okuduğu gerçek değere de baktım:
SMC tray byte=0x62 (0x60 means bypass)
Bu denemede tray kontrolü sürücüyü atlatan koşula girmiyordu, yani sistem DVD-ROM tray'i kapalı kabul ediyordu. Dolayısıyla sessizliğin nedenini burada aramaya devam etmedim.
17511'e uyarlama: adres değiştirmek yetmiyor
Sürücü, Xbox'ın USB ve kontrolcü işlevlerinin bazılarına hook yerleştiriyor. Başka bir kernel sürümündeki adresleri aynen kullanmak çalışmıyor. Çok daha önceden yedeklediğim kendi sistemime ait dosyalar üzerinden 17511'deki ilgili kernel ve XAM kodunu karşılaştırdım. (Dijital istifçilik hastalığım sağolsun :) )
XAM tarafındaki adres hesabında önemli bir hata buldum. Belleğe açılmış görüntü ile diskteki PE dosyası düzeni aynı şekilde ele alınamayınca hedef adres yanlış hesaplanmıştı.
İlk kontrol edilen XAM adresi: 0x816DA108
Doğrulanan 17511 adresi: 0x816D8D08
Teşhis logunda ilk adres okunabiliyordu ama beklenen kodla eşleşmiyordu. İkinci adresteki kod ise karşılaştırmayı geçti. Bir adresin okunabilir olması, doğru fonksiyona ait olduğu anlamına gelmiyor.
Uyarlamaya, hook kurulmadan önce beklenen kod baytlarını kontrol eden korumalar eklendi. Eşleşme yoksa sürücü o adreslere müdahale etmiyor.
Önce uygulama açılıyor mu, sonra sürücü yükleniyor mu?
İlk teşhis uygulamalarında konsolun hemen hata verdiği, siyah ekranda kaldığı veya hiçbir log oluşturmadığı denemeler oldu. Bu yüzden başlangıçta sürücüyü bile yüklemeyen, yalnızca uygulamanın giriş noktasına ulaşıldığını yazan küçük bir test kullandım.
HID17511 diagnostic v2 - passive startup probe
Application entry reached. No driver load or patches attempted.
Kernel 2.0.17511.0
Waiting 10 seconds before returning to dashboard.
Probe finished.
Bu log, en azından teşhis XEX'inin açılabildiğini gösteriyordu. Sonraki sürümlerde sırayla sürücü yükleme çağrısı, thread'in başlayıp başlamadığı ve fonksiyon kontrollerini ekledim.
Yol boyunca şu sonuçlarla da karşılaştım:
XexLoadImage status=0xC0000022
XexLoadImage status=0xC0000221
Bunlar henüz tuş eşlemesi aşamasına gelinmediğini gösteren yükleme sorunlarıydı. Ana thread üzerinden yükleme ile sistem thread'i üzerinden yüklemeyi ayrı ayrı denedim. Sonunda CPU4 üzerinde çalışan sistem thread'iyle ilerleyen yükleme yolu kullanıldı.
XEX paketlemesi de düzeltildi. SDK'nın ürettiği şifreleme yapısını koruyup gerekli medya izinlerini ve başlık özetini doğru biçimde ele almak gerekti. Önceki yeniden paketleme denemelerini çalışmış kabul etmedim; konsolda uygulamanın gerçekten açılması ve sürücünün yüklenmesi esas ölçüttü.
Eski XDK ile derleme
HID17511-DERLE.cmd
HID17511-TESHIS-DERLE.cmd
İlki sürücüyü, ikincisi teşhis uygulamasını hazırlıyordu. Başarısız derlemeden kalan eski dosyayı yeniden denememek için sürüm işaretleri de kontrol edildi.
Modülün yüklenmesi de tek başına yeterli değil
Bir noktada logda sürücünün zaten yüklü olduğu görülmeye başladı:
Existing hiddriver-17511-sdk.xex: status=0x00000000
SKIP: driver already loaded; no second load.
Sonrasında canlı hook adresleri de incelendi. Fakat bunların hiçbiri kolun tuşlarının oyuna ulaştığını tek başına kanıtlamıyordu. Bir modül bellekte bulunabilir, hook kurulmuş olabilir, hatta ikinci oyuncu LED'i yanabilir; yine de geçerli kontrolcü verisi gelmeyebilir.
Bu yüzden teşhise USB rapor sayıları, bağlantı ve ayrılma zamanları, hata durumları ve XInput tuş değişimlerini ekledim. Konsol yeniden başladıktan sonra önceki yükleme durumunun korunmadığını da hesaba katmak gerekiyordu. Yeni plugin dosyasını konsolun HDD'sine kopyaladıktan sonra konsolu tamamen kapatıp açmak testlerin bir parçası oldu.
İlk çalışan kol: PlayStation Classic
Hori ile uğraşırken PlayStation Classic kolunu da denedim. LED'in yanması başlangıçta umut veriyordu ama yönler ve tuşlar çalışmıyordu. Bu kol için bilinen tuş sırası ve yön verisi mevcut sürücüye uygun şekilde eşlendi.
PlayStation Classic
VID: 054C
PID: 0CDA
Sonunda PlayStation Classic kolu sorunsuz çalışmaya başladı. Buradaki “çalışıyor” doğrulaması, benim konsolda kolu kullanarak yaptığım denemeydi. Bu noktada MAME'de SF2CE ve Shinobi'ye dalıp epey oyalandım :)
Çalışan noktayı kaybetmemek için yedek aldım. Bundan sonra Hori veya başka bir çevirici üzerinde değişiklik yaparken PlayStation Classic'in çalışan eşlemesini korumaya dikkat ettim.
Sök-tak, ikinci oyuncu ve MAME ayarları
İlk çalışan sürümlerde konsolu kol takılıyken açtığımda cihazın devralınması her zaman istediğim gibi değildi. Aurora açıldıktan sonra USB'yi söküp takmam gereken denemeler oldu. Bunun için açılışta bağlı cihazları inceleyen ve uygun durumlarda yeniden tanıtmayı deneyen geliştirmeler yaptım.
Son sürümde sök-tak yapmadan kullanabildiğimi de gördüm. Ancak bunu bütün kollarla, tekrarlanan soğuk açılışlarda sistemli biçimde test etmediğim için GitHub'daki “henüz doğrulanmadı” notunu şimdilik bırakmayı tercih ettim.
MAME'de ise başka bir karışıklık yaşadım: PlayStation Classic ikinci oyuncudayken yönler çalışıyor, tek başına birinci oyuncudayken oyun içinde ve ayar menüsünde çalışmıyordu. MAME altındaki ilgili CFG dosyasını temizlediğimde bu sorun ortadan kalktı. Yani sürücü ve sistem çapında bir sorun değil MAME'yle sınırlı lokal bir problemmiş.
Ayrıca ikinci oyuncunun MAME ayar menüsündeki alt seçeneklere girebilmesi için emülatörün menü seçme girdisi düzenlendi. Bu, HidDriver'dan ayrı bir MAME değişikliğiydi.
PS1/PS2 çevirici ve R3 kısayolu
Daha sonra PS1/PS2 kollarını USB'ye çeviren adaptörü denedim. Bu cihaz için de tuş eşlemesi eklendi:
PS1/PS2 USB çevirici
VID: 0810
PID: 0003
PS2 DualShock koluyla oyun kontrolü çalıştı. Fakat PlayStation Classic'te fiziksel R3 olmadığı için MAME'in ayar menüsüne girmek üzere bir kombinasyona ihtiyaç duydum.
İlk denemelerde kullandığım L1 + R1 kombinasyonu, MAME'e daha önce eklediğim save/load kombinasyonlarıyla çakıştı. Birkaç değişiklikten sonra kalan düzen şu oldu:
PlayStation Classic ve denenen PS1/PS2 çeviricide:
Start + R1 + R2 = R3
PS1/PS2 çeviricide fiziksel R3'ün beklediğim şekilde davranmaması ise daha sonra bakılacak küçük işler arasında kaldı. Kombinasyonla menüye girip devam edebildiğim için Hori tarafına geri döndüm.
Bu arada SF2CE'de kare/X tuşuna atanmış orta yumrukta gecikme hissettim. Aynı hareketi başka tuşa alınca sorun görünmüyordu; diğer oyunlarda da aynı sorunu yaşamıyordum. Bunu hem PlayStation Classic hem PS2 koluyla gözlemledim. Tek oyun için çalışan sürücüyü değiştirmek istemedim; bu gözlem çözülmüş bir sürücü hatası olarak kayda geçmedi.
Hori neden diğerleri gibi çalışmadı?
Asıl uzun uğraş Hori oldu. Elimdeki model:
Hori Fighting Stick mini 4
PS4-043(U/E)
Controller üzerinde PS3/PS4 konumları olan bir anahtar var. Windows'ta iki konumda da sorunsuz çalışıyor. Xbox'ta ise bağlandığında kısa süre ikinci kontrolcü LED'i yanıyor, sonra kayboluyordu. Erken sürümlerde birkaç sök-tak sonrasında sistemin siyah ekranda kaldığı denemeler de oldu.
USB bağlantısı kesilirken hâlâ devam eden callback'lerle belleğin serbest bırakılması arasındaki sırayı bu yüzden ayrıca ele aldım. Kontrolcü hemen silinmek yerine ayrılmış olarak işaretleniyor; bekleyen işlemler ve endpoint kapatma adımları tamamlandıktan sonra kaynakları temizleniyor.
HID parser tarafındaki kullanım listesi kapasitesi de Hori'nin rapor tanımlayıcısı için yetersizdi; bu kapasite artırıldı. Ama tanımlayıcının başarıyla okunup çözümlenmesi Hori'yi tek başına çalıştırmadı.
Yaklaşık 1,8 saniyelik bağlantı
Loglar arttıkça dikkat çeken düzen ortaya çıktı: Hori, tanındıktan yaklaşık 1,8 saniye sonra HID bağlantısını kaybediyordu. Farklı USB portunda da benzer süreyi gördüm.
Bir denemede: 1804 ms
Başka bir denemede: 1805 ms
PS3 ve PS4 konumlarıyla yapılan denemelerde farklı cihaz kimlikleri ve rapor tanımlayıcıları görüldü, fakat kısa süre sonra bağlantının kapanması devam etti. Bu yüzden yalnızca “yanlış tuş haritası” veya “ikinci oyuncuya atanmış” açıklaması yeterli değildi.
Hori'ye standart HID SET_IDLE isteği gönderen sınırlı bir deneme de yapıldı. İstek başarılı sonuçlanmadı ve 1,8 saniyelik davranış değişmedi. Bu denemeyi bir çözüm olarak kabul etmedim.
USBPcap ile Windows tarafına bakmak
Kol Windows'ta çalıştığı için bu kez bilgisayardaki USB trafiğini kaydettim. USBPcap listesindeki cihaz adı ilk bakışta şaşırtıcıydı:
Xbox 360 Controller for Windows
Hori'yi çıkardığımda listeden kaybolan cihaz buydu. Windows oyun kontrolcüsü ekranında ise şu isimle görünüyordu:
Controller (Fighting Stick mini 4 kai)
Yaklaşık 39 saniyelik kayıtta Hori'nin kimliği ve arayüzü şöyleydi:
VID: 0F0D
PID: 00ED
Interface: FF / 5D / 01
Xbox'ta önce gördüğüm 00EC/00EB HID arayüzünden farklıydı. Windows kaydında 00 14 başlıklı, 20 baytlık Xbox tipi giriş paketleri geliyordu.
Ancak kaydın ilk paketinde cihaz zaten 00ED durumundaydı. Bu kayıt tek başına hangi işlemin mod değişimini başlattığını göstermiyordu. Windows'taki komutları körlemesine Xbox'a taşımak yerine, Xbox'ta kaçırdığımız ikinci bir tanınma olayı olup olmadığına bakıldı.
V20: Hori kaybolmuyor, kimlik değiştiriyor
Önceki loglar ağırlıklı olarak HID sürücüsünün gördüğü olayları kaydediyordu. Cihaz HID dışındaki bir arayüze geçince o yolun dışına çıkıyordu. V20'de bu nedenle HID/XInput ayrımından önceki ortak USB sürücü eşleştirme noktasına kayıt ekledim.
Ve aradığım geçiş yakalandı:
47022 ms: 0F0D:00EC — HID, 03/00/00
48828 ms: HID bağlantısı kapanıyor
49281 ms: 0F0D:00ED — FF/5D/01 olarak geri geliyor
Yani Hori tamamen kaybolmuyordu. İlk HID bağlantısından sonra Xbox tipi başka bir USB arayüzüyle yeniden tanınıyordu. Mevcut HID okuma yolu bu ikinci arayüzü devralmadığından tuş eşlemesi üzerinde uğraşmak sorunun esas noktasına ulaşmıyordu.
V21: Xbox'ın yerel sürücüsü neden devam etmiyor?
Bir sonraki teşhiste, 00ED arayüzünün Xbox'ın yerel kontrolcü sürücüsüne ulaşıp ulaşmadığı ve kabul edilip edilmediği izlendi.
native-add-enter
add-complete-status ... value=C0051012 caller=800FA9AC
Yerel sürücü çağrılıyordu ama ilk uygunluk kontrolünde cihazı reddediyordu. Bu, daha endpoint ve tuş verisi işleme aşamasına gelmeden gerçekleşiyordu.
Hata noktasını kodla eşleştirdim. Sorun Hori'nin yerel başlatma yolundan geçemediğiydi.
V22: Hori'nin Xbox tipi paketlerini mevcut sürücüyle okumak
Çözüm, yalnızca gözlemlediğim Hori kimliğini ve arayüzünü mevcut USB okuma ve sanal gamepad altyapısına yönlendirmek oldu:
0F0D:00ED
FF / 5D / 01
Bu modda artık HID rapor tanımlayıcısı istenmiyor. Gelen sabit biçimli 20 baytlık paketler doğrudan çözümlenip mevcut ButtonsReport yapısına aktarılıyor. Tuşlar, yönler, analog değerler ve tetikler buradan sanal XInput kontrolcüsüne gidiyor.
Xbox 360'ın işlemcisi big-endian olduğu için USB paketlerini doğrudan bir XInput yapısına dönüştürmek yerine baytlar açıkça çözümlendi. Kısa paketler, yanlış başlıklar, okuma hataları ve yeniden okumadan önce tamponun temizlenmesi de ele alındı.
HID rapor bilgisi olmayan bu yeni yol için ayrılma sırasında sanal oyuncu kaydının kaldırılması da düzenlendi. Böylece yalnızca bağlanmayı değil, cihazın daha sonra çıkarılmasını da mevcut yaşam döngüsüne oturtmak hedeflendi.
Bilgisayar tarafında Windows kaydındaki 9.712 giriş paketi yeni çözücüden geçti. Tuş bitleri, analog bayt sırası, kısa paketler ve hata durumları için de testler yapıldı. Sonraki adım yine XEX'i derleyip gerçek cihazda denemekti.
Sonunda Hori de çalıştı
V22'yi konsolda denediğimde Hori'nin yönleri ve tuşları çalıştı.
Teşhis logu da bunu destekliyordu:
HORI XINPUT routed=1 ready=1 good=9838 bad=0 errors=0
stage=3 status=00000000 length=32
Aynı logda ikinci oyuncu için yön ve tuşların basılma/bırakılma olayları da görülüyordu. Buradaki length=32 okuma tamponuyla ilgili; çözümlenen giriş mesajının 00 14 başlıklı 20 baytlık biçimiyle karıştırılmaması gerekiyor.
Son durum: 9.838 geçerli paket, sıfır bozuk paket ve sıfır USB giriş hatası. Çalışan kaynakları ve bu logu ayrıca yedekledim.
DualShock 3, Forza 4 ve PS tuşu
Hori'den sonra orijinal DualShock 3 CECHZC2E'yi USB kabloyla denedim. Temel oyun kontrolü çalıştı. Forza Motorsport 4'te kamera değiştirmeyi ararken varsayılan Xbox Back tuşunun bizim DS3 eşlemesinde Select'e karşılık geldiğini de netleştirdim.
PS tuşunun Xbox Guide olarak çalışmasını istiyordum. Kodda bu eşleme zaten vardı. Sonra kendi kolumun PS tuşunun PS3'te de zor bastığını hatırladım. Bu yüzden sırf bu gözlem üzerine sürücü eşlemesini değiştirmedim; önce fiziksel tuşu tamir edip tekrar denemeye karar verdim.
Alternatif bir Guide kombinasyonu da eklemedim. Mevcut düzenin aynen kalmasını istedim.
Henüz olmayanlar: titreşim ve SNES çevirici
Titreşimli kollarda şu anda titreşim çalışmıyor. Mevcut sürücü, oyun tarafından gelen titreşim isteğini ilgili kontrolcünün USB çıkış komutuna dönüştürüp göndermiyor.
Dolayısıyla titreşim desteği yapılacak işler arasında.
Bir diğer hedefim Nintendo SNES kolunu kullanmak. Uygun bir USB çevirici edindiğimde onun cihaz kimliğine ve raporlarına da bakıp destek eklemek istiyorum.
Şu an hangi kolları kullanabildim?
- PlayStation Classic USB kolu: oyun kontrolü çalışıyor.
- PS1/PS2 kolları: denediğim
0810:0003USB çeviriciyle çalışıyor; fiziksel R3 konusu takip listesinde. - Hori Fighting Stick mini 4:
00EDarayüzüne özel destekle çalışıyor. - Orijinal DualShock 3 CECHZC2E: USB kabloyla temel oyun kontrolü çalışıyor; titreşim henüz yok, PS tuşunu fiziksel tamirden sonra tekrar deneyeceğim.
Bunlar kendi kurulumumdaki denemeler. Bütün oyunları, bütün kernel sürümlerini veya aynı adla satılan bütün USB çeviricileri test etmiş değilim.
Kaynak GitHub'da
EinTim23'ün deposunu kendi hesabıma fork edip çalışan 17511 uyarlamasını push ettim.
Çalışma dalı: prototype/17511
Paylaşılan commit: 041c5298ad463007a903713676e629314f494a1f
Teşhis sürümü: v22
Hori desteği işareti: horixinput1
Temel değişiklikler main.cpp, HID parser, kontrolcü eşlemeleri ve 17511'e özel yardımcı başlıklarda bulunuyor. diagnostic klasöründe ayrı teşhis uygulaması var. Bu uygulama DashLaunch plugin'i değil; gerektiğinde çalıştırılan bir XEX uygulaması.
Kaynaktan derlemek için Xbox 360 XDK ve uygun Visual Studio araç zinciri gerekiyor. Konsolda kullandığım hedef VS2010 araç zinciriyle Release Retail / Xbox 360 yapılandırmasıydı.
📁 GitHub
17511 uyarlaması:
github.com/kadirdogan/hiddriver360
Türkçe durum ve yapılacaklar:
STATUS-TR.md
Bu yazıda anlatılan kaynak sürümü:
041c529 — 17511 kontrolcü desteği
Temel aldığım proje:
github.com/EinTim23/hiddriver360
Bu çalışma kendi Jasper RGH Xbox 360'ımda, 2.0.17511.0 kernel üzerinde yaptığım denemelere dayanıyor. İlk hedefim Hori ile MAME oynamaktı; yol boyunca PlayStation Classic ve PS1/PS2 kollarını da kullanabilir hale geldim. Titreşim ve SNES çevirici desteği bir sonraki işler arasında.








