TOP > プログラミング関係解説&調査 > 雑多メモ

雑多メモ

当ページの内容は、ある程度のプログラミングの知識を必要とする。
まず、プログラミング関係解説&調査をひととおり読んでいただきたい。

このページには、1ページにまとめるほどではない小ネタ、本編に関係ない没データのネタ、調査中のネタ、または調査してみたが筆者の力不足である程度までしかわからなかったことを掲載しておく。
随時変更予定。

異次元空間&ヘッドプラッカー

最終編で最初に飛ばされる真っ暗な異次元空間について。
ここは真っ暗で、どちらに進んでも行き止まりがない。
最終編のカウンターのアドレス$00:11F0には、異空間での歩数の値が入る。
初期値は$00で、$32(10進数50)以上だと背景(各シナリオの一部分)が表示されるようになり、$64(10進数100)まで増加すると階段が出現する。

各マップは左上隅を座標(X,Y) = ($00,$00)として、味方キャラ1人目(主人公)のいる座標が(X,Y)=($00:0A21,$00:0A29)に入るが、異次元空間に飛ばされた時点での座標は、(X,Y)=($09,$1A)【※10進数(9,26)】である。
座標からもわかるのだが、この空間はX方向が0~31、Yが0~63まであり、Xが31の時に更に右に移動すると0に戻るし、Yが63の時に更に下に移動すると0に戻るため、
「横32マス、縦64マスのマップが上下左右に無限ループ」
している空間である。
このため、上下左右がうまく繋がるよう、50マス以上移動時の背景画像が作られている。

100マス移動すると階段が出現するが、階段出現位置は100マス移動した時の主人公の座標で決まるので、マップ上で固定ではないことになる。

ヘッドプラッカーが出現する時の異次元空間だが、ヘッドプラッカーの座標は(X,Y) = ($00:13CC, $00:13CE)である。
このアドレスはヘッドプラッカーで固定ではなく、$00:1300~あたりにはマップ上のキャラクター(敵シンボルも、普通の街の人なども含む)の座標などが入っていて、異次元空間ではヘッドプラッカーの座標が入るアドレスである。
初期位置は($00:13CC, $00:13CE) = ($00,$00)である。
つまりヘッドプラッカー初期位置は、異次元空間マップの原点位置になる。
図で示すと以下の通りになる。

ヘッドプラッカーは主人公たちの座標へ向けて移動していく。
移動速度はおそらく味方キャラの歩行速度の1/2である。
つまり、ヘッドプラッカーが1マス移動する間に、味方は歩行だと2マス、ダッシュだと4マス、おぼろ丸のダッシュだと8マス移動できる。
おぼろ丸の場合は上にひたすら上へダッシュ移動でも、100マス移動時にヘッドプラッカーに接触せず階段が出現して脱出できるが、他キャラの場合はただ上ダッシュしているだけだと100マス移動前にヘッドプラッカーに遭遇する。
というのは、異次元空間に入ってからすぐ上にダッシュ移動し続けた場合、下図のようになってしまうのである。

味方キャラのダッシュ速度だと、ちょうど異次元空間を1周+10~16マス(75~80マス移動)くらいのあたりで、原点位置から移動してきたヘッドプラッカーに接触してしまうのである。
(ヘッドプラッカーの移動は上図とは必ずしも一致しない。右移動と下移動を繰り返してだいたい上くらいの位置で味方キャラに接触する)

ちなみに階段出現後は、階段を障害物とすることでヘッドプラッカーの移動を阻止することも可能。

ボタン判定

コントローラーのボタンを押した時のメモリアドレス&値。
以下の値は累計で入る。
つまり実際には2進数8ビットのそれぞれの位に値が入る形。
方向キー同時押しもきちんと判定されている。右+上なら$01 + $08$09が入る。

フィールド$00:0000$00:0001
$00:020A
戦闘$00:0344
$00:0347
$00:0345
$00:0348
R$10-
L$20-
X$40-
A$80-
-$01
-$02
-$04
-$08
スタート-$10
セレクト-$20
Y-$40
B-$80

戦闘中は、実際に何かを操作した時のボタン操作が別途$00:0344$00:034C$00:0345$00:034Dに入る(と思われる)。
例えばスタートボタンでポーズをかけている最中も、押したボタンは$00:0344$00:0345などに入るのだが、ポーズ中は意味がないので$00:034C$00:034Dには値が入らない。
バグ技でX+セレクトを押した時の判定は、Xボタン判定の$00:034C$40が入ると同時に、$00:034D$20が入ったかどうか、を判定している。

戦闘開始時の状態異常

世界の合言葉は森部様の「その他メモ」の最後の方に、以下のように書かれている。

敵には戦闘開始時の行動異常や状態異常が設定できるようになっているけど、
実質誰も設定されていません。王様は設定の片鱗があるけど。

これは敵データ27~28のことである。
敵データは、1体につき0~31の32バイト分の容量があるのだが、敵データ27~28の2バイトはゲームでは実際に使われていないし、値もほとんどが$00で埋まっている。
ただし、中世編にてルクレチア城で出現する偽魔王にだけ、敵データ27に「$20」という値が入っている。

戦闘開始時、敵データ28の読み込みは行われるのだが、「敵データ28と$F0で論理積をとってゼロフラグが立つ時のみ$C1/FCD4分岐」という処理があり、敵データ28がどの敵も必ず$00なので、$C1/FCD4に分岐することは絶対にない。
その、飛ばないはずの処理$C1/FCD4~を見てみると、敵データ27を状態異常にセットするサブルーチンになっているようである。敵データ28は状態異常継続時間を計算するための値になっている。
つまり$C1/FCD4~が戦闘開始時の状態異常発生処理なのだが、どの敵も「発生する状態異常継続時間 = 敵データ28 = 0」だから処理されない。
ゲーム本編では実質、没設定ということになる。

では、偽魔王に設定されている、敵データ27の$20は何の状態異常なのか。
状態異常は8種類あるが(隠し設定の首かため含む)、8種類の状態異常のON・OFFを、2進数8桁の10で表している。
2進数8桁を16進数2桁に変換した値が、敵データ27に入っているのである。

16進数$20は、2進数だと%0010 0000である。
2進数表記の時、各桁は以下のように各状態異常に対応している。

2進法の位2726252423222120
状態異常石化酔い眠りマヒ腕かため足かため首かため

$20%0010 0000)」だと、眠り状態にのみフラグが立っていることになる。
つまり偽魔王との戦闘開始時、偽魔王を眠り状態にするつもりがあったらしいのだが、実際のゲームでは採用されずに終わった、ということのようだ。
※偽魔王はルクレチア王が姿を変えられたというのが一般的な解釈だが、小学館のSFC版攻略本には偽魔王について「王を殺した犯人で、オルステッドを罠にはめるための影武者」と解説しており、ルクレチア王ではない、という解釈である。もしゲームでも眠り状態で戦闘開始になっていたら、「ルクレチア王は魔王の姿に変えられた上で玉座で眠っていた(眠らされていた?)」という解釈の方が自然であっただろう。

装備品による開戦時行動異常(特定の装備品を装備していると、戦闘開始時に特定種族の敵に一定確率で行動異常を発生させる)は実際にゲームでも発生するが、これも戦闘開始時の行動異常や状態異常のネタのひとつとして考案されていたものかもしれない。

余談ではあるが、没になったサブルーチンの処理をざっと追いかけてみた。

;X:1B00 Y:1A00とする(敵種類1、敵番号0)
;
$C1/FCC7 LDA $003C,y[$00:1A3C]   ;Aに[$00:1A3C](敵データ28)をロード
$C1/FCCA BIT #$F0                ;Aと$F0で論理積(ステータスフラグのみ変更)
$C1/FCCC BNE $06    [$FCD4]      ;ゼロフラグが立っていないとき[$FCD4]分岐
;
;どの敵も敵データ28は$00なので、この先の処理がゲームで行われることはない
$C1/FCD4 ORA #$0F                ;A(敵データ28)と$0Fで論理和
$C1/FCD6 STA $10    [$00:0310]   ;Aを[$00:0310]に書き込み
$C1/FCD8 LDA $003B,y[$00:1A3B]   ;Aに[$00:1A3B](敵データ27)をロード
$C1/FCDB STA $7E8F07,x[$7E:AA07] ;Aを[$7E:AA07](敵番号0 状態異常)に書き込み
$C1/FCDF STA $12    [$00:0312]   ;Aを[$00:0312]に書き込み
$C1/FCE1 LDA $003C,y[$00:1A3C]   ;Aに[$00:1A3C](敵データ28)をロード
$C1/FCE4 AND #$0F                ;Aと$0Fで論理積
$C1/FCE6 BEQ $09    [$FCF1]      ;ゼロフラグが立っているとき[$FCF1]分岐
$C1/FCE8 ASL A                   ;Aを算術左シフト *2
$C1/FCE9 ASL A                   ;Aを算術左シフト *2
$C1/FCEA ASL A                   ;Aを算術左シフト *2
$C1/FCEB ASL A                   ;Aを算術左シフト *2
$C1/FCEC STA $11    [$00:0311]   ;Aを[$00:0311]に書き込み = 敵データ28 & $0F * $10
$C1/FCEE JSR $35C4  [$C1:35C4]   ;[$C1:35C4]へジャンプ
;
$C1/35C4 PHX                     ;Xレジスタをスタックへプッシュ
$C1/35C5 LDA #$08                ;Aに$08をロード
$C1/35C7 STA $09    [$00:0309]   ;Aを[$00:0309]に書き込み(ループ回数$08を[$00:0309]にセット)
;
;ループ処理ここから
$C1/35C7 STA $09    [$00:0309]   ;[$00:0312]を論理右シフト(/2)
$C1/35C9 LSR $12    [$00:0312]   ;キャリーフラグが立っていないとき[$35E3]分岐
$C1/35CB BCC $16    [$35E3]      ;(CフラグONの処理)[$C1:6150]へジャンプ
;([$C1:6150]~[$C1/61A4] 戦闘乱数生成サブルーチン処理、乱数がAと[$00:033B]に入る)
$C1/35D0 CMP $10    [$00:0310]   ;A(乱数$00~$FF)と[$00:0310](敵データ28 & $0F)を減算比較(ステータスフラグ変更のみ)
$C1/35D2 BCS $0F    [$35E3]      ;キャリーフラグが立っているとき[$35E3]分岐
$C1/35D4 LDA $11    [$00:0311]   ;(CフラグONの処理)Aに[$00:0311](敵データ28 & $0F * $10)をロード
$C1/35D6 CLC                     ;キャリーフラグクリア
$C1/35D7 ADC $7E8F08,x[$7E:AA08] ;A + [$7E8F08,x]([$7E:AA08]~[$7E:$AA0F]、首/足/腕/毒/マヒ/眠/酔/石 継続時間)
$C1/35DB BCC $02    [$35DF]      ;キャリーフラグが立っていないとき[$35DF]分岐
$C1/35DD LDA #$FF                ;Aに$FFをロード
$C1/35DF STA $7E8F08,x[$7E:AA08] ;Aを[$7E8F08,x]([$7E:AA08]~[$7E:$AA0F])に書き込み
$C1/35E3 INX                     ;($C1/35CBと$C1/35D2のCフラグOFFの飛び先)Xをインクリメント +1
$C1/35E4 DEC $09    [$00:0309]   ;[$00:0309](ループ回数)をデクリメント -1
$C1/35E6 BNE $E1    [$35C9]      ;ゼロフラグが立っていないとき[$35C9]分岐
;ループ処理ここまで
;
$C1/35E8 PLX                     ;Xレジスタに値をプル
$C1/35E9 RTS                     ;サブルーチン戻り

長々と書いたが、

$C1/FCD8 LDA $003B,y[$00:1A3B]   ;Aに[$00:1A3B](敵データ27)をロード
$C1/FCDB STA $7E8F07,x[$7E:AA07] ;Aを[$7E:AA07](敵番号0 状態異常)に書き込み

結論はここである。
敵データ27がそのまま敵の状態異常がセットされるアドレスに書き込まれている。
ただ、$C1/FCD8は、$C1/FCD4以降の処理なので、実際のゲームでは読み込まれないことになる。

敵データ28から、状態異常継続時間を設定するサブルーチンもきちんと組まれている。
$C1/FCE1~が該当し、敵データ28の上1桁が状態異常発生判定用の数値、下1桁で状態異常発生時間を計算するようだ。
状態異常が格納された敵データ27を、8ビットで下の位から順に8回分、ループ処理で値が入っているか判定し、もし値が入っているのなら、戦闘乱数$00~$FFを生成して、乱数 - (敵データ28 & $0F)(※&は論理積)を計算する。
敵データ28 & $0Fは、$01~$0Fのいずれかの数のはずである。
このため、戦闘乱数$00~$FFから$01~$0Fを減算することになる。乱数が$0F以上なら、敵データ28の値に関係なく、減算結果が必ず0以上になる。

  • 乱数 - (敵データ28 & $0F)0以上の時、状態異常は発生しない(該当状態異常の継続時間は$00のまま)
  • 乱数 - (敵データ28 & $0F) が負の時、状態異常発生時間に「敵データ28 & $0F * $10」をセットする(ただし計算結果が$FF以上の場合は$FFをセットする)

この分岐を見る限り、かなりの高確率で状態異常が発生する処理のようだ。

没テキスト?

上の戦闘開始時状態異常もそうだが、本作のプログラムを見ると、設定はしたが本編では没になったデータや処理があるようだ。デバッグ用と思しきテキストもある。
没アイテムなどはSFC版攻略本にまで掲載されているし、最終編でサモに与えるアイテムの中に「満腹度が減るアイテム」があるが実際のゲームでは没になったことまでSFC版攻略本には書かれている。
とはいえ、それら没ネタは、本作にきちんと関係したもので、諸事情で採用されずに終わったのだろうということが察せられる。

システム関連のテキストデータは、$D6:AC00$D6:CFFFの領域に入っており、本作の文字データの法則に則りデコード(復元)できる。
技名、敵の名前、アイテム名、メニュー画面用のテキストなどは、没ネタも含めてだいたいこの領域に入っている。
例外として現代編のセリフもだいたいここに入っている。
没ネタにしても本作に無関係のものは(ほぼ)ない。

ところが最後の方のデータを見てみると……?

1D C5 1E D5 1E 77 B0 CE B3 CC C2 C4 BB BE D9
67 91 68 00 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
3F 3F 3F 00 20 20 20 20 20 4B 49 4C 4C 20 59 4F
55 3D 3D 00 70 6A ED DE C5 B2

↓デコード(00で改行)

古代神をほうふつとさせるキック
???????????????
     KILL YOU‥‥
タコじゃない

順に、

  • 「バベルノンキックの説明」
  • 「最終編オルステッド主人公時の操作キャラ技説明か、原始編・ざき3戦目の最後のウィンドウメッセージ」
  • 「SF編ラストバトル前のテキスト」
  • 『タコじゃない』

であるが、最後は明らかに没テキストの上、本作で登場する場面があったとは思えない謎テキストである。
テスト用の何かなのか、お遊びで入れたのか、はたまた没になったタコっぽいキャラでもいたのか、謎のままである。

「タコじゃない」といえば「ライブ・ア・ライブ」と同時期に発売の「ファイナルファンタジー6」に登場した敵「オルトロス」が、タコっぽい見た目のためにゲーム内外でネタにされるが、こちらからのネタという可能性も一応はある。



このページをシェアする

上へ