昭和六十年に行われた記念すべき第一回全国キャラバンファミコン大会、公式認定ソフト「スターフォース」。 つっても元は帝国管財なわけだが。 でもファミコンのスペックに落とし込んだのはOyajin氏の功績だよな。 というわけで、解析いってみまー(鼻声) 連射の解析をするよー。 ショットボタンを押しっぱなしにしてゼロページをみると、0x36番地が0x01から1づつ増えていって0x19になるとまた0x01に戻る動きをしている。 それで、この0x01に戻るときにショットが発射される。 また、パーサーを取ると、このループが0x01から0x0Aまでに短縮される。 というわけで、この0x36番地にon writeでブレイクポイントを仕掛けてショットボタンを押してみる。 CE77 lda $36 CE79 beq $CE8D CE7B inc $36 <<ここでブレイク CE7D lda $D0 CE7F bne $CE87 CE81 ldx #$19 CE83 lda $A1 CE85 beq $CE89 CE87 ldx #$0A CE89 cpx $36 CE8B bne $CEB4 CE8D ldx #$03 CE8F lda $03B4,x [$????] CE92 beq $CE9A CE94 dex CE95 bne $CE8F CE97 txa CE98 beq $CEB2 CE9A lda $2A CE9C sta $03B1,x [$????] CE9F lda $2B CEA1 sta $03B4,x [$????] CEA4 lda #$02 CEA6 sta $65 CEA8 lda $A1 CEAA beq $CEB0 CEAC inc $65 CEAE inc $65 CEB0 lda #$01 CEB2 sta $36 <<ここでもブレイク 0xCE81番地と0xCE87番地で、さっき調べたループ時の数値を代入しているよ。 で、0xA1番地のデータでパーサーの有無をふりわけているんだー。 代入の直後にコンペアと分岐命令があるということは、この0xCE8B番地の分岐命令を"bne $CEB4"(D0 27)から"bne $CE8D"(D0 00)にすればいいんだー。 シンクロ60連射 FC756A4C 速過ぎて弾切れしちゃうよー。 眠いんで続きは明日。 -- 以下三月三十日追記 -- 弾切れがすごいので、ショットのスピードを上げて早く画面から追い出すために、前回出てきたプログラム中のワークアドレスの内容を調べてみるよー。 0x2A 自機X座標 0x2B 自機Y座標 0x36 ショットインターバル 0x65 効果音番号 0xA1 パーサーの有無 0xD0 アドバタイズフラグ 0x03B2〜0x03B4 ショットX座標 0x03B5〜0x03B7 ショットY座標 これを見ると、ショットのY座標を更新している所を探せばいいから、0x03B5〜0x03B7にon writeでブレイクポイントを仕掛けるよー。 CEDA ldx #$03 CEDC lda $03B4,x [$03B7] CEDF beq $CEF3 CEE1 sec CEE2 sbc #$06 CEE4 ldy $A1 CEE6 beq $CEEA CEE8 sbc #$03 CEEA cmp #$09 CEEC bcs $CEF0 CEEE lda #$00 CEF0 sta $03B4,x [$03B7] <<ここでブレイク CEF3 dex CEF4 bne $CEDC CEF6 rts これを見ると、0xCEE2番地で引かれている0x06が通常時、それに0xCEE8番地で引かれている0x03を足した0x09がパーサー装備時に進むドット数みたい。 そこで、0xCEE2番地で引く数値を増やすんだけど、注意しておかなくてはいけないことがあるのー。 まず一つめは、ゲーム中のキャラクタの大きさが16×16ドットなこと。 ショットの進む速さを16ドット以上にしちゃうと、時々敵を通り抜けちゃう。 だから、この"sbc #$06"(E9 06)を"sbc #$0C"(E9 0C)にすると、パーサーを取っても0x0Fになるからちょうどいいと思うの。 それからもう一つ、0xCEEA番地の比較命令だけどー、ここで画面上に消えるショットを消すようになっているんだ。 でも、このままショットの速さを上げてしまうと、ショットを打つときの自機の位置によっては、画面上に消えた弾が下から出て来ちゃうの。 だから、ここも"cmp #$09"(C9 09)から"cmp #$0F"(C9 0F)に書き換えなきゃいけないんだ。 この0x0Fってのは、さっきも書いたパーサーを取ったときのショットのスピードだよ。 これでだいぶショットがバラけるようになったよ。 次はマジッカを全部ケラにしてみよー。 どのマジッカからケラが出るかは、得点の百の位の数字によって決まるから、得点の百の位を参照している所を探せばいいよ。 得点は、百万の位から順番に一桁づつ0x03B8〜0x03BE番地に格納されているから、百の位の0x03BC番地にon readでブレイクポイントを仕掛けるよ。 D007 eor $03BC <<ここでブレイク D00A and #$07 D00C bne $D018 D00E inc $50 この0x50番地は残機数を表しているので、直前の0xD00C番地の分岐命令を"bne $D018"(D0 0A)から"bne $D01E"(D0 00)に書き換えて潰せばいいんだ。 次はめんどうなジムダを一発で壊してみよー。 ジムダを一発撃つごとに、0xAE番地が0x01づつ増えていて、ためしに0x03で固定してみると一発で壊れるから、ここにon readでブレイクポイントを仕掛けるよー。 D035 inc $AE <<ここでブレイク D037 lda $AE <<ここでもブレイク D039 and #$03 D03B beq $D05F これは、壊れるときに分岐するようになっているから、演算結果が0x00にになるように0xD039番地を"and #$03"(29 03)を"and #$00"(29 00)に変えればいいんだ。 ショット進行速度アップ ABB0DA56 B9BC1890 マジッカ全てケラ FC92A62A ジムダ一撃必殺 FCCF7C6C -- 以下 四月七日追記 -- 鼻声は面倒なんでやめ。 無敵がうまくいかないんでちょっとひねってみる。 敵(およびパーサー)と接触すると、0xA9番地の数値(初期値0x00)がインクリメントされる。 プレイ中にこの数値を0x00以外に書き換えると、問答無用でファイナルスターは爆発する。 このインクリメント命令をつぶせば、コマンド入力での無敵と同じ「パーサーが装備できない無敵」になる。 なので、逆に死亡判定をいじるために、0xA9番地にon readでブレイクポイントをしかけてプレイ。 通常時 C7DB lda $A9 <<ここでブレイク C7DD bne $C7F5 対エリアターゲット時 C909 lda $A9 <<ここでブレイク C90B bne $C924 このbne命令をつぶしてしまえば、死亡判定に行かなくなるため無敵状態になるが、0xA9番地の数値はクリアされないため、少しでもダメージを受けていた場合、パーサーが出現した瞬間に接触判定が行われ、装備されてしまう(あまりにもダメージを受けすぎて、数値が0xFFを超えてちょうど0x00に戻っていた場合はこの限りではないが)。 がしかし、無敵では面白くないのでこのbne(0x00でなければ)命令をそれぞれbmi(0x80〜0xFFならば)命令に書き換えて、128カウント以上敵および敵弾と接触すると死亡判定に分岐するようにしてみる。 具体的には0xC7DD番地を"bne $C7F5"(D0 16)から"bmi $C7F5"(30 16)に、0xC90B番地を"bne $C924"(D0 17)から"bmi $C924"(30 17)にそれぞれ書き換える。 これで、表示はされないが擬似的にライフ制になった。 なおこの場合、敵が重なっていればその分だけ一気にダメージを受けるので、たとえばオブセスをまとめて誘導しているときなんかに誤って接触すると、一瞬で死ぬ。 さてこの状態で0xA9番地が0x00にクリアされる、つまりライフが回復するのは、次の四場面だ。 ・パーサーを装備した(カルデロンを破壊した)とき ・エリアターゲットが出現したとき ・エリアターゲットを破壊したとき ・死んだとき このうちカルデロンは、パーサーをすでに装備していると出現しない。 なのでこの制限も解除してみる。 パーサーの装備状態は既出のとおり0xA1番地で管理されているため、カルデロンが出現する直前にここにon readでブレイクポイントをしかける。 DB20 lda $A1 <<ここでブレイク DB22 bne $DB2C この0xDB22番地の"bne $DB2C"(D0 08)を"bne $DB24"(D0 00)にしてつぶせば、常にカルデロンが出現するようになる。 通常時127ダメージまで耐えられる 45E4EE94 対エリアターゲット時127ダメージまで耐えられる 45E42A96 パーサー装備中でもカルデロン出現 FCBCEA62