SMWのBGM改造の方法 0.はじめに 分かりにくいのは仕様です てか上手く説明できませんorz なので誰か文才のある人が書き直してくれるとありがたいです 1.zsnes等で吸い出したspcファイル上での改造 ROMをそのまま改造するより聞くのが楽なので先にこちらを解説します spcファイルは先頭から$100バイトがヘッダで その次の$10000バイトに保存時ARAM(AudioRAM)の状態がそのまま入っています なのでアドレスといったらARAMaddrのことをいい、 アドレス$1360はspcファイル上では$1460といった風に$100足したところをいぢると上手くいくようです $1360:bgm1dataのアドレス(2byte) $1362:bgm2dataのアドレス ... そのまんまです 例えばタイトルのBGM(#bgm = 1)は$14AAから始まるし これを$1418にするとOWのBGM(#bgm = 2)に変わります ※また変更するだけではplayerは保存時の続きから演奏しようとするため 例えばtitle.spcならば同フォルダ内にtitle.700を作り -------------------------------------------------------------------------------- m #0 2 ;SPC700 I/O Port2に0を書き込む (一旦停止) ;blktoolのコードなどで$7E1DFBに書き込むことに相当 w 2097152 ;1秒待つ m #1 2 ;1 (=#bgm)を書き込む e ;終了 -------------------------------------------------------------------------------- ってな感じで初めから再生させる必要があります ってか他の部分改造したときにバグる危険性があるのでやっとくべきです (ただしsmw0714.rarのツールで吸い出した場合は必要ありません) BGMdata(タイトルbgmなら$14AA、もちろんspcファイルでは$15AAにあります) $XXYY :一章節(?)分の曲データがあるのアドレス $00 $00 :終了コード $CC $00 $RRRR :繰り返し,CC:繰り返し回数-1(非ゼロ,$81以上なら無限ループ) RRRR:繰り返し部分のはじめのアドレス ただし基本ネスト不可 無限ループの中なら可能かもしれませんw の3つの繰り返しです 繰り返しの例 $14AA dw $14C0 ;このへんは一章節分のデータへのアドレス $14AC dw $14D0 ;ここからループ $14AE dw $14E0 ; $14B0 dw $14F0 ; $14B2 dw $1500 ; $14B4 dw $1510 ;別に同じところでもいいらしいです $14B6 dw $1510 ; $14B8 dw $1520 ;ここまでループ $14BA db $FF,$00 $14BC dw $14AC ;$14ACから無限ループ 一章節(?)分の曲データ (別に長さが決まっているわけではない) $XXXX ;チャンネル0の曲データ(使わない場合は0) $YYYY ;チャンネル1の曲データ ... $ZZZZ ;チャンネル7の曲データ (ch0-7で計16byte) ;効果音用にのけとく必要のあるchもあるかもしれません ;例 ;ch0 ch1 ch2 ch3 ch4 ch5 ch6 ch7 $14C0 dw $2448,$2471,$0000,$2495,$24AF,$0000,$0000,$0000 チャンネル毎の曲データ 00 :終了、どれかのchで終了すれば次の節に逝きます(普通ch0にのみいれます) またE9 XX YY ZZ で開始したループ部の終了コードでもあります 01-7F :音の長さ,単純に長さnの音は長さ1の音のn倍の長さです (つまり4分,8分という感じで指定するわけではありません) :また2byte続いた場合後ろのバイトを[0aaa bbbb]とすると ;&($0201+ch) = &($1268+aaa) ;これが何を意味するかはわかりませんw ;&($0211+ch) = &($1270+bbbb) ; とした後チャンネルをonにします :3byte続いたときは多分バグります 80-C5 :上の長さに従って音を出します 80:ド,81ド#,... という風に半音ずつ上がっているっぽいです でも私の音感なんて全く当てにならないですw ;C # D # E # F # G # A # B # ;----------------------------------------- ;80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D ;8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B ;9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 ;AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 ;B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 ;C # D # E F # G # A # B ;----------------------------------- ;80 81 82 83 84 85 86 87 88 89 8A 8B ;8C 8D 8E 8F 90 91 92 93 94 95 96 97 ;98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 ;A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF ;B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB ;BC BD BE BF C0 C1 C2 C3 C4 C5 と思いましたが音色の設定によってどれが何オクターブのドとかは違うかもしれません でも半音づつ上がるとかは変わらないような気がします C6 :タイ(?)ってか直前の音をのばします つまり {08 80} と {04 80 C6} は同じ音になります(多分w) C7 :休符 C8-CF :多分使われていません、機能はおそらくC7と同じです D0-D9 :太鼓とかそんな感じの音っぽいです 出力と同時に音色も変更している様なので あとでDAで元に戻すor専用のチャンネルを用意すべきです DA-FF :次の0or1or2or3バイトも使って音色の変更などをしています まだほとんど解析できていません バイト数も適当に見た程度なので間違ってる可能性もあります DA XX :音色の変更($00-$12) 一応$13はD0の音色と同じになります(普通使いません)が それ以降は確実にバグるでしょう DB XX :左右のスピーカー(?)の設定(ch毎) XX=[lr0a aaaa]とすると lr:左右の位相反転 aaaaa:音源の位置(左 1F<->00 右) DC XX YY :音源の位置を現在の位置からYYの位置までXX時間かけて移動させます YYに20以上をいれるとおそらくバグるでしょうw DE XX YY ZZ : DF : E0 XX :音量(全ch) E1 XX YY :音量(全ch)のフェードイン/アウト XX時間をかけてYYまで音量を変えます ;例 ; ;;;だんだん大きくなるドの1分音符(長さ18を16分音符としたとき) ; E0 C0 ; ; E1 C0 E0 ;volume C0->E0 (time:C0) ; 60 ; AA C6 ;長さC0のド ; E2 XX :テンポです(全ch) テンポ1では1の長さは512msecで テンポ2では1の長さは256msec, テンポnでは1の長さは512/n msec のようです E3 XX YY :XX時間かけてテンポをYYにします E4 XX :移調(?)します(全ch) 1でかくなるごとに全ての音が半音上がります おそらくFFで半音下がるものと思われます(やったことない) 80,C5の壁は一応越えられるっぽいですけど変になることもあります (てか80-C5の音でも音色によっては変になってる気がしますw) E5 XX YY ZZ : E6 : E7 XX :音量(倍率,ch毎) ($100 で100%=E0で指定した値、でも最大は$FF->ほぼ100%) E8 XX YY :ch音量をXX時間かけてYYに変化させます E9 XX YY ZZ :ループ $YYXX:ループ部のアドレス $ZZ:ループ回数 ;例 ; {blockA} ; E9 45 23 02 ;repeat $2345,3times ; {blockB} ; 00 ;$2345: ; {blockC} ; 00 ;とすると ;ACCCBの順で再生されます ; ;おそらくネスト不可です ;また ;XXXX: ; {blockA} ; E9 XXXX ?? ;(??は何でもおk) ;とした場合無限ループが作れます(この中のみ1段階ネストおkです) ;例 ;XXXX: ; {blockA} ; E9 YYYY 02 ; {blockB} ; E9 XXXX ?? ;YYYY: ; {blockC} ; 0 ;とすると ACCB ACCB ACCB .... ; EA XX : EB XX YY ZZ : EC XX YY ZZ : EE XX : EF XX YY ZZ : F0 :エコーoff F1 XX YY ZZ :エコーの設定 XX:echo Delay YY:echo FeedBack http://www.geocities.co.jp/playtown/2004/sndtech.txt参考 ZZ:echo filter type (0or1? 2は何かのコードとかぶります) $12AD+ZZ*8から8byteをDSP$0F-$7Fに書き込みます 詳細は↑参照 F2 XX YY ZZ : DD,ED,F3-FFは明らかに変なアドレスにジャンプしそうなので使えないと思われます れー $2448: F0 ;echo off DA 03 ;#tone=$03 E2 3C ;tempo=$3C E0 E6 ;vol=$E6 DB 0F ;? 18 3E ;len=$18, ??? B2 B2 B2 A6 B2 B2 B2 A6 ;GGGAGGGA 06 ;len=$06 ;$18->4分なら16分相当 B3 B0 B3 B0 B3 B0 B3 B0 B3 B0 B3 B0 B3 B0 B3 B0 ;G#FG#FG#FG#FG#FG#FG#FG#F 18 ;len=$18 B2 AD A6 ;GD#A 00 ;end 2.ROMの改造 ARAMaddr$1360以降は ow,titleなどの曲ならPCaddr$071AB5 から$161Dbyte level の曲ならPCaddr$0730DA から$41FDbyte ending の曲ならPCaddr$01E604 から$19C6byte から転送されたものなので 例えばタイトルの曲をOWの曲にするのなら PCaddr$071AB5 から2byteを$18,$14 とすればいいです また転送byte数が元のサイズを超えるときはもうちょい弄る必要がありそうです levelの曲がsize byteになってしまうのなら $00/8148 A9 D6 LDA #$ZZ $00/814A 8D 00 00 STA $0000 $00/814D A9 AE LDA #$YY $00/814F 8D 01 00 STA $0001 $00/8152 A9 0E LDA #$XX $00/8154 8D 02 00 STA $0002 とかえて $XXYYZZ: dw size dw $1360 ;destARAMaddr db data[size] dw 0 ;転送終了 dw $0500 ;ドライバ開始アドレス とすれば上手くいくかと思われます