読者です 読者をやめる 読者になる 読者になる

FC 平成天才バカボン 基礎知識

※特に断らない限りリトルエンディアンです。

仕様

iNESマッパー: 19 (私はナムコ系マッパーはよく知りません。一応NesDevWikiに解説があります)
メモリマップ

水平移動

画面内x座標 $53 とカメラx座標 $5D の和が自機のマップ内x座標(ピクセル)となります。また、x座標サブピクセルは $0178 で別に管理されています。x座標サブピクセルは静止時などに0にリセットされます。
自機の速度は $7E (16bit)で管理されており、上位Byteがピクセル、下位Byteがサブピクセルです。これは移動方向によらない絶対値です。

主な場面での上限速度を示します:

アクション 上限速度
歩行 0.875
ダッシュ 2.000
空中 1.000
しゃがみ移動 0.469
傘差し歩行 0.750
傘差し降下 0.125

どのアクションにおいても加速する際は 1/32 (≒0.031) 単位で加速します。
ダッシュ中にBを離すと 1/32 単位で減速します。また、空中または地上での滑り中に進行方向と逆のキー入力を行うと 2/32 単位で減速します。
空中減速によって速度0にすることはできますが、方向転換することはできません。

x速度 0.500 以上ではアイテム取得判定が生じません。

滑り条件

地上で一定速度以上のとき、進行方向キーを離すと滑ります。滑り中はほとんどの制御ができなくなります(方向キー入力により減速量を変えることは可能)。
滑り条件を満たしていない場合、左右どちらも押さなければ直ちに速度が0になります。また、進行方向と逆のキー入力を行うと速度を維持したまま方向転換します。いずれの場合もx座標サブピクセルは0にリセットされます。

通常は速度 0.969 以上で滑りますが、ダッシュ中にBを離す操作によって速度を 0.969 -> 0.938 -> 0.969 と変化させた場合は滑りません。
ジャンプの着地直後についてはジャンプ前の滑り条件が適用されます(例えば速度 2.000 でジャンプした場合、空中で 0.500 まで減速したとしても滑りが発生します)。地上で1F移動することで滑り条件が更新されます。

垂直移動

自機のy座標はピクセルが $59, サブピクセルが $0181 です。y速度(16bit, 絶対値)は $017D です。
このゲームはどのみちジャンプ高度制御がほぼできないのであまり深く調べてません。

座標バグ

このゲームの座標計算は色々おかしなところがあり、前フレームの座標と速度から現フレームの座標を計算すると結果が合わない場合があります。

まず、x/yいずれについてもマイナス方向への移動における繰り上がり処理が変なことになっています。座標から速度の値を引くのが普通の実装ですが、このゲームでは

という処理になっています。

また、特定のタイミングで (座標)+(速度) の値の下位1bitが切り捨てられることがあります。例えば、速度 2.000 で少し走り続けると座標値が必ず偶数になることが観察できます。これは画面内x座標とカメラx座標の整合性を保つ処理に関係していそうな気がしますが、詳細はよくわかりません。

ジャンプ

ジャンプ着地後しばらくはその場で連続ジャンプできますが、着地後歩き始めてしばらくの間はジャンプできません。

コーナーブースト

落下時にコーナーブーストが可能です(座標値が8の倍数に切り上げられます)。

ジャンプ直後の落下

ジャンプで崖の寸前に着地してから落下すると、わずかの間空中に浮いたようになり、地上と同じ行動ができます(ただしジャンプはできません)。これによりしゃがみ状態への切り替えや方向転換が可能となります。また、落下時のx座標は崖密着と崖密着+2pxの2通りがあり、ジャンプの着地位置や速度により変わるようです(座標バグが絡んでいるかも)。また、この方法で落ちる場合、ジャンプ着地位置によって落下後の着地フレームがずれる場合があるようです(空中に浮いている時間が変わる)。
なお、x座標の2pxのズレはおそらく右向き時のみ発生すると思われます。

左右/上下同時押し

地上で左右同時押しするとその場で静止し、その後進行方向キーを押せば静止前の速度で動き出します。静止中の自機グラフィックは直前の姿勢のままになります。
左右同時押し中にジャンプした場合、元の進行方向へのジャンプとなります。
左右同時押しでの静止中はアイテム取得判定がありません。
中ボス戦で左右同時押し中に被弾すると被弾音のみ発生してダメージを受けませんが、同時押し解除した瞬間にダメージを受けます。ただし左右同時押し中に複数回被弾しても受けるダメージは1回分のみです。
傘差し歩行時は左右同時押し無効です(常に右へ歩く)。
坂で速度が一定以下のときに左右同時押しするとフリーズします。これはあまり詳しく調べてませんが無限ループになっているようなので、任意コード実行などには多分繋がらないと思います(被弾など他の要素を組み合わせれば何かあるかもしれませんが)。
上下同時押しは基本的に左右同時押しと同じ効果ですが、坂でのフリーズは起こりません。

よじ登り

よじ登りを行うにはUを40F入力する必要があります。おそらく同一アクション継続フレーム数 $56 で管理されています。
よじ登り前後で座標サブピクセルは保存されます。

突っ張り登り

突っ張り登りの移動カウントは $0180 で管理されており、UまたはDを1F押すと64増え、256に達すると1px移動します。
突っ張り登り前後で座標サブピクセルは保存されます。

ハシゴ

ハシゴ登りの移動カウントは $0180 で管理されており、UまたはDを1F押すと128増え、256に達すると1px移動します。
ハシゴの途中からジャンプができます。ジャンプの向きはハシゴに掴まる前の自機の向きとなります。
ハシゴの途中からしゃがみ移動ができます。しゃがみ移動によって落下キャンセルバグへ繋げることもできます。
ハシゴ登り時に滑り条件を満たしていなければ速度を保存したまま登れます。
ハシゴ登り前後で座標サブピクセルは保存されます。

振り子

振り子ジャンプの速度は 1 + (サブ速度) となります。速度 2.000 で振り子に掴まると振り子ジャンプ速度は 1.000 となりますが、1.969 で掴まると 1.969 になります。
振り子ジャンプ前後で座標サブピクセルは保存されます。

傘高跳び

傘高跳び開始時のx速度はサブ速度となります。速度 2.000 で開始すると 0.000 に、1.969 で開始すると 0.969 になります。

壁との衝突

速度 1.938 以上で壁に当たると激突ダメージ(0.5)を受けます。
激突ダメージを受けない場合、速度が1Fに1ずつ減らされるようです。速度が0になるときx座標サブピクセルも0にリセットされます。
ただし、自機の上半身が壁に接していない場合は激突や減速が起こらないようです。例えば、高さ1の壁に向かって走ると位置を変えずに速度を増していくことができます(ハシゴ上での落下キャンセルバグでも同じ状況を作り出せます)。

落下ダメージ

一定以上のy速度で着地すると落下ダメージ(0.5)を受けます。
基本的に、高さ6マス以上から歩いて落ちるか、高さ4マス以上からジャンプして落ちると落下ダメージとなります。ただし高さ4マス以上から頭をぶつけるようにジャンプすれば落下速度が小さくなって落下ダメージを回避できることもあります。
高さ6マスの足場に掴まってから落ちてもセーフですが、高さ7マスではアウトです。

綱渡り

綱渡り中に傘を閉じてもその場から動かない限り綱の上にとどまれます。そのままジャンプすることもできます。
傘を閉じて即ジャンプすることで傘差し歩行の速度を維持したままジャンプできます。
傘を閉じた後綱の上でしばらく走れる現象を確認しましたが、条件がよくわかりません。

落下キャンセルバグ

当該記事参照。

乱数

乱数は $13-$15 で、シフトレジスタ風の処理で毎フレーム更新されます。乱数は大ボス/中ボス/一部の敵の行動に影響を与えます。
フレーム経過以外に乱数を変化させる方法はないと思われます。このため、望みの乱数を得るために一定フレームまで待つ必要が生じる場合があり、これによるフレームルールが生じることがあります。
乱数初期化ルーチンは $EC4A, 乱数更新ルーチンは $EC4F です。

パッドリセット

S,ST または T,ST,ST と入力するとリセットがかかります。

その他

割とHex-Editingに優しいゲームですが、乱数だけはどうにもならないので調整が必要になることもあります。

TAS制作支援Luaスクリプト