ロードランナーの左右同時押しについて
※以下の文章は素人が検索で集めた知識を元に構築しておりますので
事実とぜんぜん違う部分があるかと思います。決してうのみになさらないよう、お願いします。
※読者・識者よりこの理論はおかしい、との指摘があれば
即刻反省しお詫びして訂正する次第であります。
※ここにある文書は変更されることがあります。場合によっては消滅します。
※ここにある内容をバカにしたり、確かめたり、詳しそうな人に聞いたりして遊んでくさい。
最終更新:2006/4/12 ver0.5 : とりあえず書いた。ベータ版なので広めるのはまだ早いぞ。
▼問題提起▼
引用
▲▲FC版『ロードランナー』自作面▲▲
http://game.2ch.net/retro/kako/1002/10026/1002601783.html
>219 名前: XJK 投稿日: 02/03/17 02:05
>
>一応、こんなのをクリアできた、と主張してみるテスト。
>┌──────────────┐
>│員田田田#田田田田田田田田#│
>│田田田田#田田田田田田田田#│ 田:レンガ
>│田田田田#田田田田田田田田#│ ■:コンクリート
>│田田田田#田田田田田田田田#│ #:はしご
>│田田田田#田田田田田田田田#│ −:バー
>│田田田田#田田田田田■■■#│ 凹:落とし穴
>│田田田田#田田田田田■▲■#│ 己:脱出はしご
>│田田田田#田田田田田■■■田│ ▲:金塊
>│田田田田#田田田田田田田田田│ 員:ロボット
>│田田田田#田田田田田田田田田│ ♀:ランナー
>│田田田田#田田田田田田田田田│ ×:空白
>│田田田田#−田田田田田田田田│ (ランナー配置せず)
>│田田田田−#田田田田田田田田│
>└──────────────┘
>↑をクリアするには左右同時押しのキー操作バグが必須なんだけど、
>ホンモノのファミコン(藁)の十字キーで左右同時押しができるのか、
>是非とも誰か教えてくれ〜ょ。
(前書き)
コントローラーを分解せずに、
ファミコンの、ロードランナーにおける、「左右同時押し」を成立させるためには
何をどうすべきかをここに示すものとする予定であります。
なお、噂では分解すればごく普通に同時押しができるそうです。私は試していませんが。
(問題の補足)
なお、この面では復活した敵が地下から這い上がってくる前に
- "左右同時押しのキー操作バグが必須"について
内部的に←は2、→は1、OR演算すると"3"となります。
このときランナーがどういう動きをするかは今は関係ないです。
敵に、キー情報(←+→=3)をはしご(=3)と誤認識させることが必須、ということです。
敵はキー情報をはしごと誤認識したとき、通常のはしごと同じように登り、
地下から這い出てきます。これが必須なのです。
(バグによって)金塊を持った状態になる必要がありますが、
今回の検証では見なかったことにします。
ここでは「左右同時押しをして、敵が地下から這い上がってくるには
どうするか」を主題とします。
(理論編に行く前に、前提)
・プログラムは上から下へ順番に実行する
・ファミコンはキーを全部同時に取得しない
・キーは押した瞬間に押された状態になる ←たぶんこの辺に穴がある
この前提がすでにダメである場合、以下の文はなかったことに…
(理論編)
ファミコンのプログラムではキーの取得は順番に行われます。
全部同時には取得しないのです。パッド情報をリセット後、
A、B、スタート、セレクト、↑、↓、←、→ の順で取得されます。
キー入力取得のコード
アドレス 命令 対象 値 クロック数 コメント C1EC LDY imm 08 2 //ループカウンタ Y=8(ボタン数) C1EE TXA none 2 //←ループ先 (初期Xは0) C1EF ASL none 2 //左シフト C1F0 TAX none 2 //キー情報はXに保存 C1F1 LDA abs 4016 4 //キー取得。ABスタートセレクト↑↓←→の順で取得 C1F4 JSR abs C20D 6 //サブルーチンC20Dへ C1F7 BNE Z==0 F5 3 //ループで8回まわす→
サブルーチンC20D
命令 対象 値 クロック数 AND imm 01 2 //キーが入っていたらZ=0 BEQ Z==1 01 2 //Z=1ならINXはしない。 INX none 2 //キーが入っていたらXに+1 DEY none 2 //ループカウンタ減少 RTS none 6 //サブルーチンから戻る
ぱっと見、プログラムが「←」取得から「→」取得の間、
命令数にして11命令、動作にして約33クロック。
この間に「←」から「→」にキーを入れれば「左右同時押し」が
成立すると考えられます。
と、思ったらもっと余裕がありました。
ファミコンのキー情報は、情報リセットの命令を受けない限り
1回押したら押しっぱなしとして扱うそうなのです。
なので、最初の「A」の取得から「→」を取得するまで、約240クロックの間に
「←、→」を入力できていれば良いのです。
ここでクロック数から、実際の時間に直して計算してみます。
えーと、ファミコンのCPUは約1.79MHzで動作するそうなので、
1クロック=約 0.55μ秒(1μ秒=100万分の1秒)
240クロック=約134.08μ秒
134.08μ秒に1回、「←」「→」と入っていればよい、と。
ちょっとストップ。
かなり先まで書いてから気づいたのですが、
ここから先、「←」と「→」を連打で入力することを考えます。
十字キー連打で100%成立させるためには「←」「→」の入力のほかに、
逆順の「→」「←」でも成立したほうが都合が良いのです。
「最初の「A」の取得から「→」を取得するまで、約240クロックの間」を
「最初の「A」の取得から「←」を取得するまで、約200クロックの間」で考えます。
では気を取り直して。
えーと、ファミコンのCPUは約1.79MHzで動作するそうなので、
1クロック=約 0.55μ秒(1μ秒=100万分の1秒)
200クロック=約111.73μ秒
111.73μ秒に1回、「←」と「→」が入っていればよい、と。
←→←→←→←→←→←→と連続で入力するとして、
111.73μ秒以下で入力すれば同時押しが成立ということです。
このとき←キーを秒間何連射かと計算すると、
←を押している時間=111.73μ秒/1000/1000=0.00011173 秒
→を押している時間=111.73μ秒/1000/1000=0.00011173 秒
(1 / 0.00011173秒+0.00011173秒)
= 秒間 4475連打 (ただし、←のみの回数)(連打速度Aとする)
これは1秒間も続ける必要はなく、敵がはしご登る6フレーム、0.1秒間行えばよいです。
ふうやれやれ。
異議あり!
(入力についての再考)
上記の連打速度は←→を理論値で入力したときのものです。
つまり、←を離した瞬間に→を入力できたとするものです。
これは実際には無理です。
ファミコンのコントローラーではおそらく、
←・→・←・→・←・→・←・→・←・→・←・→
のように何も押していない時間が存在するでしょう。
やはりキーを離している時間があるとして考えて計算しなおしましょう。
- キーを押している時間と離している時間が同じ場合
1/(0.00011173+0.00011173*(1/3))
= 秒間 6712連打(ただし、←のみの回数)(連打速度B)以上のように、秒間に押さなければならない連打速度は、ボタンを押している時間で変化し、
- 押している時間が一瞬である場合
1/0.00011173
= 秒間 8950連打(ただし、←のみの回数)(連打速度C)
片手あたり 秒間4475回〜秒間8950回の間となります
連打数じゃ、ピンとこねぇよ!
(入力に必要な指の速度)
これを行うには指を秒速何メートルで動かせばよいでしょうか。
ちゃんと測っていませんがボタンを押すのにストロークが1.5mmほど。
十字キーは右を押すと左が浮くので3mm指を上下させる必要があり、往復で6mm。
6mmを、秒間4475連打(連打速度A)では、秒速何メートルか、というと
0.006m×4475(回/秒)=26.85 m/秒
時速にして96kmくらい、でしょうか。
違います違います、上記の計算方法は成立しません。
「秒間4475連打(連打速度A)」ですむのは「←を離した瞬間に→を押す」という前提があるのです。
つまり、0秒で←から指を離し、同時に0秒で→を押さなければなりません。
出っ張った→ボタンを押すのに0秒なんてことはありえません。
正しい指の速度の計算式は、
キーの厚さを、何も押さなかった時間で、割る
になります。
あらためて押した時間が半々の場合と、一瞬押して離す場合を計算してみます。
- 秒間6712連打(連打速度B)の場合の計算
←を離してから→を押すまでに 0.00011173*(1/3) 秒の時間があります。
この間に 3mm 指を動かすことができればよいので、
0.003m÷(0.00011173*(1/3))
=80.55 m/秒
- 秒間8950連打(連打速度C)の場合の計算
←を離してから→を押すまでに 0.00011173*(1/2) 秒の時間があります。
この間に 3mm 指を動かすことができればよいので、
0.003m÷(0.00011173*(1/2))
=53.70 m/秒
連打回数が増えたほうが指の必要速度が減ってますが、
これは瞬間的に必要な速度の計算だからです。
秒間6712連打(連打速度B)をする場合、ボタンを押しっぱなしにする時間が発生し、指は、
動く・止まる(押しっぱなし)・動く・止まる(押しっぱなし)・動く
これを繰り返すのでロスが多く、そのロスを補うため速く動かさないといけません。
(導き出された結論) 片手につき、 |
(備考)
● 左右同時押しを100%成功させる必要があったか
・問題になった面で敵が這い上がってくるには左右同時押しを100%成立する必要はない。
敵が動くのは平均3フレーム中2フレームであり、なおかつ、ある1フレームで失敗しても
1フレーム分落下するだけなので、次の1フレームで成功させれば失敗はチャラである。
4回分成功させればよいものの、確率分布とか分散とかの計算は
ワタクシはできないので100%を求めた。
● 確実性を求めたことについて
・コントローラーの検知では→を最後に取得するので
←、→の順に操作する場合は約240クロックの猶予があるが、
→、←の順で操作する場合は約200クロックで済まさなければならない。
「左右同時押しを100%成立させる」とするため、
今回は常に200クロック以内という計算をした。
240クロック=134.08μ秒
240クロックでは指の速さは44.75 m/秒、秒間7458連打ですむ。
この連打の場合、ある134.08μ秒において「→、←」と入力したときに
左右同時押しが成功しない確率が出る。
要するに連打が足りないのである。
● 連打ではなく、タイミングを見計らって操作する場合
プログラムがキーを感知した瞬間がわかり、見計らって→キーを押すことができるとする。
この場合「134.08μ秒以内に←から→へ入力を変更する」操作となり、
瞬間的に 22.37 m/秒(時速80km)の速度ですむ。
これを0.083秒間にタイミングを見て4回行う。
(敵が4回はしごを登れば地下から這い出てくる。
敵が4回行動するのにかかる時間は最短5フレーム=0.083秒である)
● マンガの表現について
今回の説明は、ファミコンのキーのストロークが1.5mmとして計算している。
だが、ゲームセンターあらしなどでは巨大なコントローラーを使っている。
アレの厚さ約3cmと仮定して計算すると、
0.030m÷(0.00011173*(1/2))
=537.00 m/秒
音速がたしか 340 m/秒。ああ、やっぱり超えるんだ。
(実践・実験)
(補足)
この考察は「ファミコンで」「ロードランナーのキー取得プログラムを用いて」
計算されたものです。
ゲームが違えばキー取得のアルゴリズムが変わり、計算に用いたクロック数などが変化します。
また、計算には間違い・勘違い・嘘・大げさ・紛らわしいなどの成分が含まれる可能性がありますので
くれぐれも盲信しないようお願いいたします。
この文書は誤りに気づいたときにある日突然改ざんされたり消滅したりする可能性があります。
参考ページ
クロックと時間計算方法(1クロックが何秒かの計算)
http://www.117.ne.jp/~show/pc8801/tech88/3070.html
ファミコンの動作クロック数(何MHzか)
http://www.geocities.co.jp/SiliconValley/5604/tech/Famicom3.html
命令のクロック数
http://crystal.freespace.jp/pgate1/nes/nes_cpu.htm#clock
注釈
敵の移動は1フレームごとに
休む、動く、動く
となっています。
連打時の「敵が動く6フレーム」は最長時間で計算し、
タイミングを見計らって操作では「5フレーム」というのは最短時間で計算しています。