前回のエントリの内容を踏まえると、ルイーダ以外でのキャラクターの追加・削除のやりかたが見えてきます。追加時には以下の手順を踏めばいいということになります。
- 空いているPC用アドレスを探して必要情報をセット
- $7E36E2の数を操作
- $7E36E8-の配列に追加したキャラクターのアドレスを挿入して1つずらす
1点注意があり、この操作をミスると登録済みのキャラクターが消えるという最悪のバグが起きることもあるのでテストは十分やるべき、ということです。追加キャラクター用のステータスをハードコードするのもどうかと思ったので新規に「追加キャラクター用ステータス」という固定長データを定義しました。
- $3EEADE 追加キャラクターステータス(32Byte*5rec)
範囲(Byte) | 範囲(bit) | 意味 |
---|---|---|
0-1Byte | 名前(固定文字列ID) | |
2Byte | 0-3bit | 職業ID |
2Byte | 4bit | 性別 |
2-3Byte | 5-3bit(7bit) | 性格 |
3-4Byte | 4-2bit(7bit) | レベル |
4-5Byte | 3-3bit(9bit) | 力 |
5-6Byte | 4-4bit(9bit) | 素早さ |
6-7Byte | 5-5bit(9bit) | 身の守り |
7-8Byte | 6-6bit(9bit) | 体力 |
8-9Byte | 7-7bit(9bit) | 賢さ |
10-11Byte | 0-0bit(9bit) | 運の良さ |
11-12Byte | 1-2bit(10bit) | 最大HP |
12-13Byte | 3-4bit(10bit) | 最大MP |
14-16Byte | 初期状態経験値 | |
17Byte | 装備武器アイテムID | |
18Byte | 装備鎧アイテムID | |
19Byte | 装備盾アイテムID | |
20Byte | 装備兜アイテムID | |
21Byte | 装備装飾品アイテムID | |
22-23Byte | 呪文習得状態1 | |
24-25Byte | 呪文習得状態2 | |
26-27Byte | 呪文習得状態3 | |
28-29Byte | 呪文習得状態4 | |
30-31Byte | 呪文習得状態5 |
これといって特筆するべきこともなく、必要なステータスをベタっと横に並べただけです。アイテムは12個まで持てますが、余り必要性を感じなかったので装備品以外は何も持たない、ということにしました。次に追加用のSRを実装します。
- SR: $05EE00 追加キャラクターをPC領域に追加(Y=インデックス)(新SR)
05EE00 | JSL $C41962 | SR: $041962 | 新規PC追加可能かチェック+追加可能オフセットを返す(可能c=off, 全バンク用) |
---|---|---|---|
05EE04 | BCC #$01 | if(c==off) goto $05EE07 | |
05EE06 | RTL | return | |
05EE07 | PHX | Push X | |
05EE08 | JSL $C90501 | SR: $090501 引数:1#$00 引数:2#$0020 引数:3#$FEEADE 引数:4#$00 | 構造体アクセス Y番目の先頭アドレスをDP($00,第4引数)にセット |
05EE13 | LDY #$0000 | Y=#$0000 | |
05EE16 | LDA $00 | A=$(DP[$00])+Y | |
05EE18 | JSL $C1BA53 | SR: $01BA53 | 固定文字列開始アドレス取得(オフセットをYにセット) |
05EE1C | LDX #$0000 | X=#$0000 | |
05EE1F | JSL $C1BACC | SR: $01BACC | 固定文字列デコード+オフセットインクリメント |
05EE23 | SEP #$20 | m=on(A/M:8b) | |
05EE25 | STA $4056,X | $4056+X=A | |
05EE28 | REP #$20 | m=off(A/M:16b) | |
05EE2A | INX | X++ | |
05EE2B | CMP #$00AC | A==#$00AC? | |
05EE2E | BNE #$EF | if(z==off) goto $05EE1F | |
05EE30 | PLX | Pull X | |
05EE31 | JSL $C4195E | SR: $04195E | PC追加場所を#$00で初期化(全バンク用) |
05EE35 | JSL $C42FD5 | SR: $042FD5 | 名前変更 |
05EE39 | JSL $C41966 | SR: $041966 | 存在フラグオン(全バンク用) |
05EE3D | LDA #$0002 | A=#$0002 | |
05EE40 | JSL $C42DFA | SR: $042DFA | ルイーダの酒場に預けられるかのフラグ変更 |
05EE44 | LDY #$000E | Y=#$000E | |
05EE47 | LDA $00 | A=$(DP[$00])+Y | |
05EE49 | STA $0001,X | $0001+X=A | |
05EE4C | LDY #$0010 | Y=#$0010 | |
05EE4F | LDA $00 | A=$(DP[$00])+Y | |
05EE51 | AND #$00FF | A&=#$00FF | |
05EE54 | STA $0003,X | $0003+X=A | |
05EE57 | LDY #$0002 | Y=#$0002 | |
05EE5A | LDA $00 | A=$(DP[$00])+Y | |
05EE5C | AND #$000F | A&=#$000F | |
05EE5F | STA $0021,X | $0021+X=A | |
05EE62 | LDY #$0002 | Y=#$0002 | |
05EE65 | LDA $00 | A=$(DP[$00])+Y | |
05EE67 | AND #$0010 | A&=#$0010 | |
05EE6A | BEQ #$06 | if(z==on) goto $05EE72 | |
05EE6C | LDA #$0020 | A=#$0020 | |
05EE6F | STA $001F,X | $001F+X=A | |
05EE72 | PEA #$0000 | Push #$0000 | |
05EE75 | PEA #$0FE0 | Push #$0FE0 | |
05EE78 | PEA #$0002 | Push #$0002 | |
05EE7B | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EE7F | JSL $C42F06 | SR: $042F06 | 性格変更 |
05EE83 | PEA #$0000 | Push #$0000 | |
05EE86 | PEA #$07F0 | Push #$07F0 | |
05EE89 | PEA #$0003 | Push #$0003 | |
05EE8C | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EE90 | JSL $C43021 | SR: $043021 | レベル変更 |
05EE94 | PEA #$0000 | Push #$0000 | |
05EE97 | PEA #$0FF8 | Push #$0FF8 | |
05EE9A | PEA #$0004 | Push #$0004 | |
05EE9D | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EEA1 | JSL $C43450 | SR: $043450 | 力変更 |
05EEA5 | PEA #$0000 | Push #$0000 | |
05EEA8 | PEA #$1FF0 | Push #$1FF0 | |
05EEAB | PEA #$0005 | Push #$0005 | |
05EEAE | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EEB2 | JSL $C43707 | SR: $043707 | 素早さ変更 |
05EEB6 | PEA #$0000 | Push #$0000 | |
05EEB9 | PEA #$3FE0 | Push #$3FE0 | |
05EEBC | PEA #$0006 | Push #$0006 | |
05EEBF | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EEC3 | JSL $C41F3B | SR: $041F3B | 身の守り変更 |
05EEC7 | PEA #$0000 | Push #$0000 | |
05EECA | PEA #$7FC0 | Push #$7FC0 | |
05EECD | PEA #$0007 | Push #$0007 | |
05EED0 | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EED4 | JSL $C4358A | SR: $04358A | 体力変更 |
05EED8 | PEA #$0000 | Push #$0000 | |
05EEDB | PEA #$FF80 | Push #$FF80 | |
05EEDE | PEA #$0008 | Push #$0008 | |
05EEE1 | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EEE5 | JSL $C43841 | SR: $043841 | 賢さ変更 |
05EEE9 | PEA #$0000 | Push #$0000 | |
05EEEC | PEA #$01FF | Push #$01FF | |
05EEEF | PEA #$000A | Push #$000A | |
05EEF2 | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EEF6 | JSL $C43988 | SR: $043988 | 運のよさ変更 |
05EEFA | PEA #$0000 | Push #$0000 | |
05EEFD | PEA #$07FE | Push #$07FE | |
05EF00 | PEA #$000B | Push #$000B | |
05EF03 | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EF07 | JSL $C43073 | SR: $043073 | 最大HP変更 |
05EF0B | JSL $C43183 | SR: $043183 | 現在HP変更 |
05EF0F | PEA #$0000 | Push #$0000 | |
05EF12 | PEA #$1FF8 | Push #$1FF8 | |
05EF15 | PEA #$000C | Push #$000C | |
05EF18 | JSL $C90717 | SR: $090717 | RAM上情報取得 |
05EF1C | JSL $C43263 | SR: $043263 | 最大MP変更 |
05EF20 | JSL $C43366 | SR: $043366 | 現在MP変更 |
05EF24 | LDA #$0000 | A=#$0000 | |
05EF27 | JSL $C43460 | SR: $043460 | 力小数点部分変更 |
05EF2B | JSL $C43717 | SR: $043717 | 素早さ小数点部分変更 |
05EF2F | JSL $C42349 | SR: $042349 | 体力・身の守り小数点部分0セット |
05EF33 | JSL $C43851 | SR: $043851 | 賢さ小数点部分変更 |
05EF37 | JSL $C43998 | SR: $043998 | 運のよさの小数点部分変更 |
05EF3B | LDY #$0016 | Y=#$0016 | |
05EF3E | LDA $00 | A=$(DP[$00])+Y | |
05EF40 | STA $0024,X | $0024+X=A | |
05EF43 | LDY #$0018 | Y=#$0018 | |
05EF46 | LDA $00 | A=$(DP[$00])+Y | |
05EF48 | STA $0026,X | $0026+X=A | |
05EF4B | LDY #$001A | Y=#$001A | |
05EF4E | LDA $00 | A=$(DP[$00])+Y | |
05EF50 | STA $0028,X | $0028+X=A | |
05EF53 | LDY #$001C | Y=#$001C | |
05EF56 | LDA $00 | A=$(DP[$00])+Y | |
05EF58 | STA $002A,X | $002A+X=A | |
05EF5B | LDY #$001E | Y=#$001E | |
05EF5E | LDA $00 | A=$(DP[$00])+Y | |
05EF60 | STA $002C,X | $002C+X=A | |
05EF63 | STZ $40 | DP($40)=#$00 | |
05EF65 | LDY #$0011 | Y=#$0011 | |
05EF68 | LDA $00 | A=$(DP[$00])+Y | |
05EF6A | AND #$00FF | A&=#$00FF | |
05EF6D | BEQ #$06 | if(z==on) goto $05EF75 | |
05EF6F | JSL $C44777 | SR: $044777 | PCにアイテムを持たせる |
05EF73 | INC $40 | DP($40)++ | |
05EF75 | LDY #$0012 | Y=#$0012 | |
05EF78 | LDA $00 | A=$(DP[$00])+Y | |
05EF7A | AND #$00FF | A&=#$00FF | |
05EF7D | BEQ #$06 | if(z==on) goto $05EF85 | |
05EF7F | JSL $C44777 | SR: $044777 | PCにアイテムを持たせる |
05EF83 | INC $40 | DP($40)++ | |
05EF85 | LDY #$0013 | Y=#$0013 | |
05EF88 | LDA $00 | A=$(DP[$00])+Y | |
05EF8A | AND #$00FF | A&=#$00FF | |
05EF8D | BEQ #$06 | if(z==on) goto $05EF95 | |
05EF8F | JSL $C44777 | SR: $044777 | PCにアイテムを持たせる |
05EF93 | INC $40 | DP($40)++ | |
05EF95 | LDY #$0014 | Y=#$0014 | |
05EF98 | LDA $00 | A=$(DP[$00])+Y | |
05EF9A | AND #$00FF | A&=#$00FF | |
05EF9D | BEQ #$06 | if(z==on) goto $05EFA5 | |
05EF9F | JSL $C44777 | SR: $044777 | PCにアイテムを持たせる |
05EFA3 | INC $40 | DP($40)++ | |
05EFA5 | LDY #$0015 | Y=#$0015 | |
05EFA8 | LDA $00 | A=$(DP[$00])+Y | |
05EFAA | AND #$00FF | A&=#$00FF | |
05EFAD | BEQ #$06 | if(z==on) goto $05EFB5 | |
05EFAF | JSL $C44777 | SR: $044777 | PCにアイテムを持たせる |
05EFB3 | INC $40 | DP($40)++ | |
05EFB5 | LDA $40 | A=DP($40) | |
05EFB7 | PHA | Push A | |
05EFB8 | LDA #$0000 | A=#$0000 | |
05EFBB | CMP $01,S | A>=Stack($01)? | |
05EFBD | BCS #$09 | if(c==on) goto $05EFC8 | |
05EFBF | PHA | Push A | |
05EFC0 | JSL $C44C67 | SR: $044C67 | 指定インデックスのアイテムを装備する? |
05EFC4 | PLA | Pull A | |
05EFC5 | INC | A++ | |
05EFC6 | BRA #$F3 | goto $05EFBB | |
05EFC8 | PLA | Pull A | |
05EFC9 | RTL | return |
やたらと長いですが、やっていることは上の固定長データの特定のインデックス(このSRをコールした時点でYレジスタにセットされていることが前提)の値を右から左にせっせとくべているだけです。元は登録所で新規PCを追加する処理をコピーしているだけなのでそれほど難しいことではありません。このSRから戻ってくるとXレジスタに追加したキャラクターの開始アドレスがセットされます。続けてこのキャラクターをパーティに追加するSRを実装します。
- SR: $05F000 追加キャラクターをパーティに追加する(新SR)
05F000 | PHA | Push A | |
---|---|---|---|
05F001 | PHX | Push X | |
05F002 | CMP #$0000 | A==#$0000? | 追加先はパーティ |
05F005 | BNE #$0D | if(z==off) goto $05F014 | |
05F007 | LDA $36E2 | A=$36E2 | |
05F00A | CMP #$0004 | A>=#$0004? | パーティ人数が4人なら何もしない |
05F00D | BCS #$54 | if(c==on) goto $05F063 | |
05F00F | INC $36E2 | $36E2++ | |
05F012 | BRA #$26 | goto $05F03A | |
05F014 | CMP #$0002 | A==#$0002? | 追加先はルイーダ |
05F017 | BNE #$09 | if(z==off) goto $05F022 | |
05F019 | INC $36E4 | $36E4++ | |
05F01C | CLC | c=off | |
05F01D | ADC $36E2 | A+=($36E2+c) | |
05F020 | BRA #$18 | goto $05F03A | |
05F022 | CMP #$0004 | A==#$0004? | |
05F025 | BNE #$3C | if(z==off) goto $05F063 | |
05F027 | LDA $36E6 | A=$36E6 | |
05F02A | CMP #$0003 | A>=#$0003? | |
05F02D | BCS #$34 | if(c==on) goto $05F063 | |
05F02F | INC $36E6 | $36E6++ | |
05F032 | CLC | c=off | |
05F033 | ADC $36E2 | A+=($36E2+c) | |
05F036 | CLC | c=off | |
05F037 | ADC $36E4 | A+=($36E4+c) | |
05F03A | ASL | A<<1 | |
05F03B | STA $00 | DP($00)=A | |
05F03D | LDA #$0000 | A=#$0000 | |
05F040 | CLC | c=off | |
05F041 | ADC $36E2 | A+=($36E2+c) | |
05F044 | CLC | c=off | |
05F045 | ADC $36E4 | A+=($36E4+c) | |
05F048 | CLC | c=off | |
05F049 | ADC $36E6 | A+=($36E6+c) | |
05F04C | ASL | A<<1 | |
05F04D | TAY | Y=A | |
05F04E | LDA $36E8,Y | A=$36E8+Y | |
05F051 | STA $36EA,Y | $36EA+Y=A | |
05F054 | DEY | Y– | |
05F055 | DEY | Y– | |
05F056 | CPY $00 | Y>=DP($00)? | |
05F058 | BCS #$F4 | if(c==on) goto $05F04E | |
05F05A | LDY $00 | Y=DP($00) | |
05F05C | PLA | Pull A | |
05F05D | STA $36E8,Y | $36E8+Y=A | |
05F060 | SEC | c=on | |
05F061 | PLA | Pull A | |
05F062 | RTL | return | |
05F063 | CLC | c=off | |
05F064 | PLX | Pull X | |
05F065 | PLA | Pull A | |
05F066 | RTL | return |
Aレジスタには追加先(0:パーティ 2:酒場 4:一時待機)、Xレジスタには追加PCの開始アドレスをセットしていることが前提です。実際使っているのはパーティへの追加だけなので、その他の場合については正しく動作しないかもしれません。やっていることは追加先の最後に追加PCのアドレスをセットし、それ以外の配列の要素を1つずつ後ろにずらす、というものです。実際にこれらのSRをどう使うかを例示します。
- SR: $0F09AF 呪術師の家イベント処理(新SR)
省略 | |||
---|---|---|---|
0F09CB | LDY #$0003 | Y=#$0003 | 呪術師の追加キャラクターID |
0F09CE | JSL $C5EE00 | SR: $05EE00 | 追加キャラクターをPC領域に追加(Y=インデックス) |
省略 | |||
0F09D5 | LDA #$0000 | A=#$0000 | 追加先をパーティに指定 |
0F09D8 | JSL $C5F000 | SR: $05F000 | 追加キャラクターをパーティに追加する |
省略 |
呪術師の家イベント処理全体としてはNPCとして表示されている呪術師がパーティの最後尾に移動する処理などがありますが、関係ないので省きます。
コメント