【NSMBW】上投げパッチの制作後記
こんにちは。ReaZ0nです。今回は、某チームのModに送ったコードの制作後記となります。このnoteでは、例としてPOWブロックのパッチを公開します。
アドレスとyaml
北欧版のアドレスは以下の通りです。日本版ではアドレスが違った記憶があります。
x速度:0x8089287c
y速度:0x80892880
それぞれ、速度の値をストアする命令が入っているアドレスです。
yamlはこんな感じになります。blで分岐させて、もとのアドレスに返ってくるようにしています。
# daPowBlock_c
- name: ThrowUpPOWSpeedX
type: branch_insn
branch_type: bl
src_addr_pal: 0x8089287c
target_func: 'ThrowUpPOWSpeedX'
- name: ThrowUpPOWSpeedY
type: branch_insn
branch_type: bl
src_addr_pal: 0x80892880
target_func: 'ThrowUpPOWSpeedY'
x速度
x速度はプレイヤーの速度をそのまま使用しています。
.global ThrowUpPOWSpeedX # 0x8089287c
ThrowUpPOWSpeedX:
# r24: unused, r30, r28: this ptr, r29: player ptr, r23: player->input
mflr r24 # maybe safe register
mr r3, r23
bl getHeldUp__14dPlayerInput_c # returns 0 (not held) or 2 (held) to r3
cmpwi r3, 0
beq L_restorePOWX
# Set this->speed.x
lfs f31, 0xe8(r29) # this->speed.x = player->speed.x
#stfs f31, 0xf4(r30) # this->speedmax.x = player->speed.x
# Make flag for to set speed.y
li r3, 0x1
stw r3, 0x248(sp)
b L_returnPOWX
L_restorePOWX:
li r3, 0x0 # Delete flag for to set speed.y
stw r3, 0x248(sp)
L_returnPOWX:
oris r3, r3, 0x0090 # restore r3
stfs f31, 0xe8(r30)
mtlr r24
li r24, 0
blr
ストア部
以下のコードで、LRレジスタの値をr24に移動しています。
mflr r24
入力取得部
r23にはplayerの入力情報のメモリアドレスが入っていたので、それをr3に移動して入力を取得しています。
getHeldUp__14dPlayerInput_c(0x8005E4F0)の引数は、第一引数のplayerポインターだけなので、r4以降のレジスタに値が入っていても問題はありません。
関数が実行されたときに上入力がされていた場合、戻り値として2を返します。なので、0(他の入力)と比較して0の場合にのみrestoreに分岐させています。
mr r3, r23
bl getHeldUp__14dPlayerInput_c # returns 0 (not held) or 2 (held) to r3
cmpwi r3, 0
beq L_restorePOWX
速度保存部
r29にもplayerポインターが入っていたのでそれを使っています。
スプライトのポインター+0xe8のメモリアドレスにx速度が保存されているので、この場合はプレイヤーのx速度を取得しています。
# Set this->speed.x
lfs f31, 0xe8(r29) # this->speed.x = player->speed.x
フラグ立て部
y速度でまた入力を取得するのは面倒なので、スタックポインタ(sp)もといr1+0x248のメモリアドレスにフラグを立てるようにしています。
上入力があった場合は1です。
# Make flag for to set speed.y
li r3, 0x1
stw r3, 0x248(sp)
b L_returnPOWX
y速度
y速度は、置換用のデータを新たにfloat型で定義し、それをもとのデータと置換しています。
.global ThrowUpPOWSpeedY # 0x80892880
ThrowUpPOWSpeedY:
lwz r3, 0x248(sp) # isFlag enable
cmpwi r3, 0x0
beq L_returnPOWY
# Set this->speed.y
lis r3, ThrowUpPOWSpeedYfloat@ha
lwz r3, ThrowUpPOWSpeedYfloat@l(r3)
stw r3, 0xec(r30) # really stupid way
lfs f1, 0xec(r30)
L_returnPOWY:
oris r3, r3, 0x0090 # restore r3
stfs f1, 0xec(r30)
blr
.data
.align 4
ThrowUpPOWSpeedYfloat:
.float 7.0
フラグ取得部
先述したフラグを取得し分岐しています。この場合、0(上未入力)の場合に分岐ですね〜。
lwz r3, 0x248(sp) # isFlag enable
cmpwi r3, 0x0
beq L_returnPOWY
置換部
コードの一番下で定義しているfloatを読み込んで置換します。
r30はthisポインタ、+0xecはy速度の保存場所です。
# Set this->speed.y
lis r3, ThrowUpPOWSpeedYfloat@ha
lwz r3, ThrowUpPOWSpeedYfloat@l(r3)
stw r3, 0xec(r30) # really stupid way
lfs f1, 0xec(r30)
定義部
float型でY速度を定義しています。これを、上記の置換部で用いています。
.data
.align 4
ThrowUpPOWSpeedYfloat:
.float 7.0
迫真完成部
完成したコードはこちらです。
.text
.align 4
#ifndef __MWERKS__
.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4
.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
.set r30,30; .set r31,31; .set f0,0; .set f2,2; .set f3,3
.set f1,1; .set f8,8; .set f9,9; .set f10,10; .set f11,11;
.set f30,30; .set f31,31
#endif
.set sp, 1
# Made by ReaZ0n23 Inspired in NewerGEM.
################################################################################
.extern getHeldUp__14dPlayerInput_c
################################################################################
.global ThrowUpPOWSpeedX # 0x8089287c
ThrowUpPOWSpeedX:
# r24: unused, r30, r28: this ptr, r29: player ptr, r23: player->input
mflr r24 # maybe safe register
mr r3, r23
bl getHeldUp__14dPlayerInput_c # returns 0 (not held) or 2 (held) to r3
cmpwi r3, 0
beq L_restorePOWX
# Set this->speed.x
lfs f31, 0xe8(r29) # this->speed.x = player->speed.x
# Make flag for to set speed.y
li r3, 0x1
stw r3, 0x248(sp)
b L_returnPOWX
L_restorePOWX:
li r3, 0x0 # Delete flag for to set speed.y
stw r3, 0x248(sp)
L_returnPOWX:
oris r3, r3, 0x0090 # restore r3
stfs f31, 0xe8(r30)
mtlr r24
li r24, 0
blr
################################################################################
.global ThrowUpPOWSpeedY # 0x80892880
ThrowUpPOWSpeedY:
lwz r3, 0x248(sp) # isFlag enable
cmpwi r3, 0x0
beq L_returnPOWY
# Set this->speed.y
lis r3, ThrowUpPOWSpeedYfloat@ha
lwz r3, ThrowUpPOWSpeedYfloat@l(r3)
stw r3, 0xec(r30) # really stupid way
lfs f1, 0xec(r30)
L_returnPOWY:
oris r3, r3, 0x0090 # restore r3
stfs f1, 0xec(r30)
blr
################################################################################
.data
.align 4
ThrowUpPOWSpeedYfloat:
.float 7.0
じゃ