
背景
すべては、任天堂のいわゆる「スターカタログ」で私がこれを見たという事実から始まりました。

これは、SNESのゲームパッド形式のWii用コントローラーです。 知らない人のために、WiiではNES(「ダンディ」として知られています)、SNES(別名スーパー任天堂)、ニンテンドー64、その他のクラシックコンソールからゲームを正式に購入してプレイできることをお伝えします。 そのようなゲームを完全にプレイするには、通常のゲームパッドである「クラシックコントローラー」を追加で購入する必要があります。
したがって、元のSNESコントローラの形式のこのゲームパッドは、ゲームを購入するときに取得したスターについてのみ、スターカタログで「購入」できます。 簡単に言えば、通常のゲームパッドのように店で簡単に購入することはできません。これは、狭い円で非常に高く評価されているためです。
それはすぐに私に思い浮かびました-なぜ、あなたはWiesに接続できるアダプターを作ってみませんか(古典的なコントローラーはコンソールに直接接続されず、コンソールに直接接続されません) 。 そのため、Wiioutの拡張ポートがどのように構成されているのかという疑問が生じました。
理論
少しググリングした後、通常のI²Cプロトコルがあることが判明しました。 コネクタは、アース、電源、クロック、データ、接続の定義の5つの接点を使用します(そこに電源を入れるだけです)。

接続されたデバイスには、アドレス0x52が必要です。 送信されたデータは何らかの理由で暗号化されています。 Wiimote自体が送信する512ビットキーの使用とは何ですか。 復号化には、単純な式が使用されます。
decrypted_byte = (encrypted_byte ^ table1[address%8]) + table2[address%8]
なぜ暗号化があるのですか? できません 幸いなことに、Wiiデバイスを作成するための既製のライブラリがあることがすぐに明らかになりました。
code.google.com/p/circle-of-current/wiki/WiiExtensionLibrary
AVRマイクロコントローラーのI²Cおよび暗号化/復号化との連携を実装しています。 ちょうど私が必要なもの! デバイスIDを置き換えて、送信されたデータでアレイを埋めるだけです。 いくつかのデバイスIDは次のとおりです。

(wiibrew.orgからの情報)
Classic Controllerに興味がありました。 次に、データを送信する形式を理解する必要がありました。 また、6バイトが送信されます。

LXおよびLYは左アナログスティック(0-63)、RXおよびRYは右アナログスティック(0-31)、LTおよびRTはアナログシフト(0-31)、BD {L、R、U、D }-クロス、B {ZR、ZL、A、B、X、Y、+、H、-、LT、RT}-ボタン。1が押され、0が押されます。
すべてがやや紛らわしいです...また、電源を入れると、デバイスが較正され、アナログから最初に受信した値が中心とみなされることを考慮する価値があります。
実装
したがって、ゲームパッドの落ち着いた位置では、6バイトのデータの配列は次のようになります。
unsigned char but_dat[6]; // struct containing button data but_dat[0] = 0b01011111; // RX<4:3> LX<5:0> but_dat[1] = 0b11011111; // RX<2:1> LY<5:0> but_dat[2] = 0b10001111; // RX<0> LT<4:3> RY<4:0> but_dat[3] = 0b00000000; // LT<2:0> RT<4:0> but_dat[4] = 0b11111111; // BDR BDD BLT B- BH B+ BRT 1 but_dat[5] = 0b11111111; // BZL BB BY BA BX BZR BDL BDU
スティックの最上位ビットはゼロで、それ以外はすべて1です。 これにより、スティックが中央にあり、すべてのボタンが押されているデータが送信されます。
これらの値を必要な値に変更し、Wiimoteがデバイスに問い合わせたときに送信するだけです。 Dandyのゲームコントローラを接続することを最初に決めました。 つまり 押されたボタンを読んでWiimoteに送信し、古典的なコントローラーをクリックするのを模倣します。
Dandyのゲームパッドからデータを読み取る方法については説明しません。このトピックは非常にボロボロで、非常に簡単に行われます。 たとえば、次の記事を読むことができます: habrahabr.ru/post/191936 authorship KurilkaRymin ただし、ここではこのためのコードを示しますが、非常に小さいです。
uint8_t get_nes_gamepad() { uint8_t gamepad_data = 0; NES_PORT &= ~(1<<LATCH_PIN); // Latch int b; for (b = 0; b < 8; b++) { NES_PORT &= ~(1<<CLOCK_PIN); // Clock _delay_us(10); gamepad_data |= (((NES_PORT_PIN>>DATA_PIN)&1)<<b); NES_PORT |= 1<<CLOCK_PIN; // Clock _delay_us(10); } NES_PORT |= 1<<LATCH_PIN; // Latch _delay_us(10); return gamepad_data; }
dendivskyコントローラーが時間を割いていないという事実を除いて、すべてが遅延と問題なく機能しました。私は積極的にアルコールで接触を拭かなければなりませんでした。 ところで、奇妙なことに、彼らは3.3ボルトで十分な電力を持っていますが、どこでも5ボルトで電力が供給されていると書いています。 レベルコンバーターを作成する心構えは既にできていましたが、その必要はありませんでした。
これで、ダンディーのコントローラーでNESのWiiゲームをプレイできます。 または、NESからネイティブコントローラーで取得した場合。 ただし、不正なターボボタンが存在する場合にのみ異なります。
計画:
- SNESおよびN64コントローラーをサポートする
- ボードをエッチングして、すべてを美しいケースに入れます
プロジェクトソースコード : github.com/ClusterM/nes2wii
主な情報源 : wiibrew.org/wiki/Wiimote/Extension_Controllers