rewrite 6xE4 logic
This commit is contained in:
@@ -18,10 +18,19 @@ start:
|
||||
|
||||
|
||||
|
||||
# Change class_flags check to read only low 16 bits
|
||||
.data <VERS 0x800142D8 0x80014308 0x800146A0 0x800142B8 0x800142F0 0x800142F0 0x800142B8 0x80014330>
|
||||
# Don't allow 6x0A to set total_damage; we'll do it with 6xE4 instead
|
||||
.data <VERS 0x800F6064 0x800F6368 0x800F6594 0x800F6490 0x800F6308 0x800F6308 0x800F64A0 0x800F6468>
|
||||
.data 4
|
||||
lhz r0, [r28 + 0x2E6]
|
||||
.address <VERS 0x800F6064 0x800F6368 0x800F6594 0x800F6490 0x800F6308 0x800F6308 0x800F64A0 0x800F6468>
|
||||
nop
|
||||
|
||||
|
||||
|
||||
# Enemy state setup debug hook
|
||||
.data <VERS 0x800F60BC 0x800F63C0 0x800F65EC 0x800F64E8 0x800F6360 0x800F6360 0x800F64F8 0x800F64C0>
|
||||
.data 4
|
||||
.address <VERS 0x800F60BC 0x800F63C0 0x800F65EC 0x800F64E8 0x800F6360 0x800F6360 0x800F64F8 0x800F64C0>
|
||||
bl debug_hook1
|
||||
|
||||
|
||||
|
||||
@@ -29,19 +38,7 @@ start:
|
||||
.data <VERS 0x804C00C4 0x804C37FC 0x804C5C9C 0x804C5A3C 0x804C0894 0x804C0D74 0x804C5314 0x804C57B4>
|
||||
.data 8
|
||||
.data 0x00E40006 # subcommand=0xE4, flags=6
|
||||
.data 0x800041C0 # on_6xE4
|
||||
|
||||
|
||||
|
||||
# Hooks in 6x0A handler
|
||||
.data <VERS 0x800F605C 0x800F6360 0x800F658C 0x800F6488 0x800F6300 0x800F6300 0x800F6498 0x800F6460>
|
||||
.data 4
|
||||
.address <VERS 0x800F605C 0x800F6360 0x800F658C 0x800F6488 0x800F6300 0x800F6300 0x800F6498 0x800F6460>
|
||||
bl on_handle_6x0A_set_total_damage
|
||||
.data <VERS 0x800F60BC 0x800F63C0 0x800F65EC 0x800F64E8 0x800F6360 0x800F6360 0x800F64F8 0x800F64C0>
|
||||
.data 4
|
||||
.address <VERS 0x800F60BC 0x800F63C0 0x800F65EC 0x800F64E8 0x800F6360 0x800F6360 0x800F64F8 0x800F64C0>
|
||||
bl on_handle_6x0A_call_object_update_handler
|
||||
.data 0x800041C0 # handle_6xE4
|
||||
|
||||
|
||||
|
||||
@@ -49,90 +46,82 @@ start:
|
||||
.data <VERS 0x80013A78 0x80013AA8 0x80013E18 0x80013A58 0x80013A90 0x80013A90 0x80013A58 0x80013AD0>
|
||||
.data 4
|
||||
.address <VERS 0x80013A78 0x80013AA8 0x80013E18 0x80013A58 0x80013A90 0x80013A90 0x80013A58 0x80013AD0>
|
||||
bl on_TObjectV8047c128_add_hp
|
||||
bl on_TObjectV8047c128_add_hp_with_sync
|
||||
|
||||
|
||||
|
||||
# subtract_hp callsites in TObjectV8047c128_subtract_hp_if_in_state_2
|
||||
# subtract_hp callsites in TObjectV8047c128_subtract_hp_if_not_in_state_2
|
||||
.data <VERS 0x800114F0 0x80011510 0x800117A0 0x800114C0 0x80011508 0x80011508 0x800114C0 0x80011538>
|
||||
.data 4
|
||||
.address <VERS 0x800114F0 0x80011510 0x800117A0 0x800114C0 0x80011508 0x80011508 0x800114C0 0x80011538>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
# subtract_hp callsites in TObjectV8047c128_v18_handle_hit_special_effects
|
||||
.data <VERS 0x80011C50 0x80011C80 0x80011F48 0x80011C30 0x80011C68 0x80011C68 0x80011C30 0x80011CA8>
|
||||
.data 4
|
||||
.address <VERS 0x80011C50 0x80011C80 0x80011F48 0x80011C30 0x80011C68 0x80011C68 0x80011C30 0x80011CA8>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80011CA0 0x80011CD0 0x80011F98 0x80011C80 0x80011CB8 0x80011CB8 0x80011C80 0x80011CF8>
|
||||
.data 4
|
||||
.address <VERS 0x80011CA0 0x80011CD0 0x80011F98 0x80011C80 0x80011CB8 0x80011CB8 0x80011C80 0x80011CF8>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80011D1C 0x80011D4C 0x80012014 0x80011CFC 0x80011D34 0x80011D34 0x80011CFC 0x80011D74>
|
||||
.data 4
|
||||
.address <VERS 0x80011D1C 0x80011D4C 0x80012014 0x80011CFC 0x80011D34 0x80011D34 0x80011CFC 0x80011D74>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80011D6C 0x80011D9C 0x80012064 0x80011D4C 0x80011D84 0x80011D84 0x80011D4C 0x80011DC4>
|
||||
.data 4
|
||||
.address <VERS 0x80011D6C 0x80011D9C 0x80012064 0x80011D4C 0x80011D84 0x80011D84 0x80011D4C 0x80011DC4>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80012774 0x800127A4 0x80012A6C 0x80012754 0x8001278C 0x8001278C 0x80012754 0x800127CC>
|
||||
.data 4
|
||||
.address <VERS 0x80012774 0x800127A4 0x80012A6C 0x80012754 0x8001278C 0x8001278C 0x80012754 0x800127CC>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80012AE8 0x80012B18 0x80012DE0 0x80012AC8 0x80012B00 0x80012B00 0x80012AC8 0x80012B40>
|
||||
.data 4
|
||||
.address <VERS 0x80012AE8 0x80012B18 0x80012DE0 0x80012AC8 0x80012B00 0x80012B00 0x80012AC8 0x80012B40>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80012C58 0x80012C88 0x80012F50 0x80012C38 0x80012C70 0x80012C70 0x80012C38 0x80012CB0>
|
||||
.data 4
|
||||
.address <VERS 0x80012C58 0x80012C88 0x80012F50 0x80012C38 0x80012C70 0x80012C70 0x80012C38 0x80012CB0>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x8001300C 0x8001303C 0x80013304 0x80012FEC 0x80013024 0x80013024 0x80012FEC 0x80013064>
|
||||
.data 4
|
||||
.address <VERS 0x8001300C 0x8001303C 0x80013304 0x80012FEC 0x80013024 0x80013024 0x80012FEC 0x80013064>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
# subtract_hp callsites in TObjectV8047c128_v17_accept_hit
|
||||
.data <VERS 0x80013454 0x80013484 0x800137F4 0x80013434 0x8001346C 0x8001346C 0x80013434 0x800134AC>
|
||||
.data 4
|
||||
.address <VERS 0x80013454 0x80013484 0x800137F4 0x80013434 0x8001346C 0x8001346C 0x80013434 0x800134AC>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x8001354C 0x8001357C 0x800138EC 0x8001352C 0x80013564 0x80013564 0x8001352C 0x800135A4>
|
||||
.data 4
|
||||
.address <VERS 0x8001354C 0x8001357C 0x800138EC 0x8001352C 0x80013564 0x80013564 0x8001352C 0x800135A4>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80013644 0x80013674 0x800139E4 0x80013624 0x8001365C 0x8001365C 0x80013624 0x8001369C>
|
||||
.data 4
|
||||
.address <VERS 0x80013644 0x80013674 0x800139E4 0x80013624 0x8001365C 0x8001365C 0x80013624 0x8001369C>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x800137AC 0x800137DC 0x80013B4C 0x8001378C 0x800137C4 0x800137C4 0x8001378C 0x80013804>
|
||||
.data 4
|
||||
.address <VERS 0x800137AC 0x800137DC 0x80013B4C 0x8001378C 0x800137C4 0x800137C4 0x8001378C 0x80013804>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x800138EC 0x8001391C 0x80013C8C 0x800138CC 0x80013904 0x80013904 0x800138CC 0x80013944>
|
||||
.data 4
|
||||
.address <VERS 0x800138EC 0x8001391C 0x80013C8C 0x800138CC 0x80013904 0x80013904 0x800138CC 0x80013944>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80013E00 0x80013E30 0x800141A0 0x80013DE0 0x80013E18 0x80013E18 0x80013DE0 0x80013E58>
|
||||
.data 4
|
||||
.address <VERS 0x80013E00 0x80013E30 0x800141A0 0x80013DE0 0x80013E18 0x80013E18 0x80013DE0 0x80013E58>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
.data <VERS 0x80013F04 0x80013F34 0x800142A4 0x80013EE4 0x80013F1C 0x80013F1C 0x80013EE4 0x80013F5C>
|
||||
.data 4
|
||||
.address <VERS 0x80013F04 0x80013F34 0x800142A4 0x80013EE4 0x80013F1C 0x80013F1C 0x80013EE4 0x80013F5C>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
# subtract_hp callsites in TObjectV8047c128_v16
|
||||
.data <VERS 0x80014770 0x800147A0 0x80014B38 0x80014750 0x80014788 0x80014788 0x80014750 0x800147C8>
|
||||
.data 4
|
||||
.address <VERS 0x80014770 0x800147A0 0x80014B38 0x80014750 0x80014788 0x80014788 0x80014750 0x800147C8>
|
||||
bl on_TObjectV8047c128_subtract_hp
|
||||
|
||||
|
||||
|
||||
# subtract_hp callsites in TObjectV8047c128_v23_give_poison_damage
|
||||
.data <VERS 0x80017290 0x800172C0 0x80017808 0x80017270 0x800172A8 0x800172A8 0x80017270 0x800172E8>
|
||||
.data 4
|
||||
.address <VERS 0x80017290 0x800172C0 0x80017808 0x80017270 0x800172A8 0x800172A8 0x80017270 0x800172E8>
|
||||
bl on_TObjectV8047c128_subtract_hp_without_sync
|
||||
bl on_TObjectV8047c128_subtract_hp_with_sync
|
||||
|
||||
|
||||
|
||||
@@ -140,206 +129,242 @@ start:
|
||||
.deltaof code_start, code_end
|
||||
.address 0x800041C0
|
||||
code_start:
|
||||
on_6xE4: # (G_6xE4* cmd @ r3) -> void
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 8], r3
|
||||
|
||||
li r4, 2
|
||||
lhbrx r3, [r3 + r4]
|
||||
bl get_enemy_entity
|
||||
handle_6xE4: # [std] (G_IncrementEnemyDamage_Extension_6xE4* cmd @ r3) -> void
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 0x08], r31
|
||||
stw [r1 + 0x0C], r30
|
||||
mr r31, r3
|
||||
|
||||
cmplwi r3, 0
|
||||
beq on_6xE4_skip
|
||||
li r3, 2
|
||||
lhbrx r3, [r31 + r3]
|
||||
cmplwi r3, 0x1000
|
||||
blt handle_6xE4_return
|
||||
cmplwi r3, 0x1B50
|
||||
bge handle_6xE4_return
|
||||
bl state_for_enemy # auto* st = state_for_enemy(cmd->header.entity_id);
|
||||
|
||||
lwz r4, [r1 + 8]
|
||||
li r5, 4
|
||||
lhbrx r6, [r4 + r5]
|
||||
extsh r6, r6
|
||||
lhz r7, [r3 + 0x2E4]
|
||||
add r6, r6, r7
|
||||
lhz r7, [r3 + 0x2B8]
|
||||
cmp r6, r7
|
||||
bgt on_6xE4_use_r7
|
||||
li r7, 0
|
||||
cmp r6, r7
|
||||
blt on_6xE4_use_r7
|
||||
sth [r3 + 0x2E4], r6
|
||||
b on_6xE4_skip
|
||||
on_6xE4_use_r7:
|
||||
sth [r3 + 0x2E4], r7
|
||||
lhz r4, [r3 + 6] # st->total_damage
|
||||
li r5, 0x04
|
||||
lhbrx r5, [r31 + r5] # cmd->hit_amount
|
||||
add r4, r4, r5 # st->total_damage + cmd->hit_amount
|
||||
li r5, 0x0A
|
||||
lhbrx r5, [r31 + r5] # cmd->max_hp
|
||||
cmp r4, r5
|
||||
blt handle_6xE4_damage_less_than_max_hp
|
||||
|
||||
on_6xE4_skip:
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
sth [r3 + 6], r5 # st->total_damage = cmd->max_hp;
|
||||
li r4, 0x0C
|
||||
bl send_debug_info # TODO: Remove this when no longer necessary
|
||||
lwz r4, [r3]
|
||||
andi. r0, r4, 0x800
|
||||
bne handle_6xE4_return
|
||||
ori r4, r4, 0x800
|
||||
stw [r3], r4 # st->game_flags |= 0x800;
|
||||
|
||||
# Send 6x0A with dead flag
|
||||
stw [r1 + 0x14], r4
|
||||
li r6, 0x12
|
||||
sthbrx [r1 + r6], r5
|
||||
lhz r6, [r31 + 2]
|
||||
oris r6, r6, 0x0A03
|
||||
stw [r1 + 0x0C], r6
|
||||
andi. r6, r6, 0xFF0F
|
||||
sth [r1 + 0x10], r6
|
||||
addi r3, r1, 0x0C
|
||||
bl send_and_handle_60
|
||||
b handle_6xE4_return
|
||||
|
||||
handle_6xE4_damage_less_than_max_hp:
|
||||
cmpwi r4, 0
|
||||
bge handle_6xE4_damage_nonnegative
|
||||
li r4, 0
|
||||
handle_6xE4_damage_nonnegative:
|
||||
sth [r3 + 6], r4 # st->total_damage = std::max<int16_t>(st->total_damage + cmd->hit_amount, 0);
|
||||
li r4, 0x0C
|
||||
mr r30, r3
|
||||
bl send_debug_info
|
||||
|
||||
li r3, 2
|
||||
lhbrx r3, [r31 + r3]
|
||||
bl get_enemy_entity
|
||||
cmplwi r3, 0
|
||||
beq handle_6xE4_return
|
||||
mr r4, r30
|
||||
lwz r12, [r3 + 0x18]
|
||||
lwz r12, [r12 + 0x140]
|
||||
mtctr r12
|
||||
bctrl
|
||||
|
||||
handle_6xE4_return:
|
||||
lwz r30, [r1 + 0x0C]
|
||||
lwz r31, [r1 + 0x08]
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
|
||||
|
||||
on_handle_6x0A_set_total_damage: # (G_6x0A* cmd @ r30) -> int16_t @ r3
|
||||
# Nonstandard convention (patched callsite is not a call or return); must
|
||||
# save and restore r0
|
||||
mflr r4
|
||||
stw [r1 + 0x04], r4
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 0x08], r0
|
||||
|
||||
lhz r3, [r30 + 2]
|
||||
bl get_enemy_entity
|
||||
|
||||
cmplwi r3, 0
|
||||
beq on_handle_6x0A_set_total_damage_not_loaded
|
||||
|
||||
lhz r4, [r3 + 0x2E4]
|
||||
lhz r5, [r3 + 0x2B8]
|
||||
lhz r3, [r30 + 6]
|
||||
cmp r3, r5
|
||||
bgt on_handle_6x0A_set_total_damage_use_r5
|
||||
cmp r3, r4
|
||||
blt on_handle_6x0A_set_total_damage_use_r4
|
||||
b on_handle_6x0A_set_total_damage_return
|
||||
on_handle_6x0A_set_total_damage_use_r4:
|
||||
mr r3, r4
|
||||
b on_handle_6x0A_set_total_damage_return
|
||||
on_handle_6x0A_set_total_damage_use_r5:
|
||||
mr r3, r5
|
||||
b on_handle_6x0A_set_total_damage_return
|
||||
|
||||
on_handle_6x0A_set_total_damage_not_loaded:
|
||||
lhz r3, [r30 + 6]
|
||||
|
||||
on_handle_6x0A_set_total_damage_return:
|
||||
lwz r0, [r1 + 0x08]
|
||||
addi r1, r1, 0x20
|
||||
lwz r4, [r1 + 4]
|
||||
mtlr r4
|
||||
state_for_enemy: # [/r4] (uint16_t entity_id @ r3) -> EnemyState* @ r3
|
||||
# return &enemy_states[entity_id & 0x0FFF];
|
||||
lwz r4, [r13 - <VERS 0x44F4 0x44EC 0x44CC 0x44CC 0x44DC 0x44DC 0x44BC 0x447C>]
|
||||
andi. r3, r3, 0x0FFF
|
||||
mulli r3, r3, 0x0C
|
||||
add r3, r3, r4
|
||||
blr
|
||||
|
||||
|
||||
|
||||
on_handle_6x0A_call_object_update_handler: # (TObjectV8047c128* this @ r3, EnemyState* ene_st @ r4, void (*vfn)(TObjectV8047c128* this @ r3, EnemyState* ene_st @ r4) @ r12) -> void
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 0x08], r3
|
||||
stw [r1 + 0x0C], r4
|
||||
stw [r1 + 0x10], r12
|
||||
on_TObjectV8047c128_add_hp_with_sync: # [std] (TObjectV8047c128* ene @ r3, int16_t amount @ r4) -> void
|
||||
li r5, 1
|
||||
b on_add_or_subtract_hp
|
||||
on_TObjectV8047c128_subtract_hp_with_sync: # [std] (TObjectV8047c128* ene @ r3, int16_t amount @ r4) -> void
|
||||
li r5, 0
|
||||
on_add_or_subtract_hp: # [std] (TObjectV8047c128* ene @ r3, int16_t amount @ r4, bool is_add @ r5) -> void
|
||||
lhz r0, [r3 + 0x1C]
|
||||
cmplwi r0, 0x1000
|
||||
blt on_add_or_subtract_hp_skip_send
|
||||
cmplwi r0, 0x1B50
|
||||
bge on_add_or_subtract_hp_skip_send
|
||||
|
||||
lwz r5, [r3 + 0x30]
|
||||
lwz r7, [r4]
|
||||
or r5, r5, r7
|
||||
andi. r5, r5, 0x0800
|
||||
bne on_handle_6x0A_call_object_update_handler_return
|
||||
lhz r5, [r4 + 6]
|
||||
lhz r6, [r3 + 0x2B8]
|
||||
cmp r5, r6
|
||||
blt on_handle_6x0A_call_object_update_handler_return
|
||||
lwz r11, [r13 - <VERS 0x50B8 0x50B0 0x5090 0x5090 0x50A0 0x50A0 0x5080 0x5040>]
|
||||
cmplwi r11, 0
|
||||
beq on_add_or_subtract_hp_skip_send
|
||||
|
||||
ori r7, r7, 0x0800
|
||||
stw [r4], r7
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 0x14], r29
|
||||
stw [r1 + 0x18], r30
|
||||
stw [r1 + 0x1C], r31
|
||||
mr r29, r3
|
||||
mr r30, r4
|
||||
mr r31, r5
|
||||
|
||||
lwz r11, [r13 - <VERS 0x50B8 0x50B0 0x5090 0x5090 0x50A0 0x50A0 0x5080 0x5040>]
|
||||
cmplwi r11, 0
|
||||
beq on_handle_6x0A_call_object_update_handler_return
|
||||
lhz r3, [r29 + 0x1C]
|
||||
bl state_for_enemy # EnemyState* st = state_for_enemy(ene->entity_id);
|
||||
|
||||
addi r10, r1, 0x14
|
||||
li r9, 0x1C
|
||||
lhbrx r5, [r3 + r9]
|
||||
oris r5, r5, 0x0A03
|
||||
stw [r10], r5
|
||||
lhz r5, [r3 + 0x2C]
|
||||
li r9, 4
|
||||
sthbrx [r10 + r9], r5
|
||||
lhz r5, [r4 + 6]
|
||||
li r9, 6
|
||||
sthbrx [r10 + r9], r5
|
||||
lwz r5, [r4]
|
||||
stw [r10 + 8], r5
|
||||
mr r3, r11
|
||||
mr r4, r10
|
||||
li r5, 0x0C
|
||||
bl send_60
|
||||
mr r5, r30
|
||||
cmplwi r31, 0
|
||||
beq on_add_or_subtract_hp_skip_negate_amount
|
||||
neg r5, r5
|
||||
on_add_or_subtract_hp_skip_negate_amount:
|
||||
|
||||
on_handle_6x0A_call_object_update_handler_return:
|
||||
lwz r3, [r1 + 0x08]
|
||||
lwz r4, [r1 + 0x0C]
|
||||
lwz r12, [r1 + 0x10]
|
||||
mtctr r12
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
li r4, 0x1C
|
||||
lhbrx r4, [r29 + r4]
|
||||
oris r4, r4, 0xE403
|
||||
stw [r1 + 0x08], r4
|
||||
li r4, 0x0C
|
||||
sthbrx [r1 + r4], r5
|
||||
li r4, 6
|
||||
lhbrx r4, [r3 + r4]
|
||||
sth [r1 + 0x0E], r4
|
||||
li r4, 0x32C
|
||||
lhbrx r4, [r29 + r4]
|
||||
sth [r1 + 0x10], r4
|
||||
li r4, 0x2B8
|
||||
lhbrx r4, [r29 + r4]
|
||||
sth [r1 + 0x12], r4
|
||||
mr r3, r11
|
||||
addi r4, r1, 0x08
|
||||
li r5, 0x0C
|
||||
bl send_60
|
||||
|
||||
on_add_or_subtract_hp_tail_call:
|
||||
mr r3, r29
|
||||
mr r4, r30
|
||||
mr r5, r31
|
||||
lwz r31, [r1 + 0x1C]
|
||||
lwz r30, [r1 + 0x18]
|
||||
lwz r29, [r1 + 0x14]
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
|
||||
on_add_or_subtract_hp_skip_send:
|
||||
cmplwi r5, 0
|
||||
beq on_add_or_subtract_hp_tail_call_subtract_hp
|
||||
b TObjectV8047c128_add_hp
|
||||
on_add_or_subtract_hp_tail_call_subtract_hp:
|
||||
b TObjectV8047c128_subtract_hp
|
||||
|
||||
|
||||
|
||||
# TODO: Remove this when no longer necessary
|
||||
debug_hook1:
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
mr r6, r3
|
||||
mr r7, r4
|
||||
mr r3, r4
|
||||
li r4, 0x0C
|
||||
li r5, -1
|
||||
bl send_debug_info
|
||||
mr r3, r6
|
||||
mr r4, r7
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
mtctr r12
|
||||
bctr
|
||||
|
||||
|
||||
|
||||
on_TObjectV8047c128_subtract_hp_without_sync: # (TObjectV8047c128* this @ r3, int16_t amount @ r4)
|
||||
li r5, 2
|
||||
b on_TObjectV8047c128_hp_change
|
||||
on_TObjectV8047c128_add_hp: # (TObjectV8047c128* this @ r3, int16_t amount @ r4)
|
||||
li r5, 1
|
||||
b on_TObjectV8047c128_hp_change
|
||||
on_TObjectV8047c128_subtract_hp: # (TObjectV8047c128* this @ r3, int16_t amount @ r4)
|
||||
li r5, 0
|
||||
send_debug_info: # (void* data @ r3, uint32_t size @ r4, uint16_t what @ r5) -> void
|
||||
mflr r0
|
||||
stw [r1 + 0x04], r0
|
||||
stw [r1 - 0x04], r3
|
||||
stw [r1 - 0x08], r4
|
||||
stw [r1 - 0x0C], r5
|
||||
stw [r1 - 0x10], r6
|
||||
stw [r1 - 0x14], r7
|
||||
stw [r1 - 0x18], r8
|
||||
stw [r1 - 0x1C], r9
|
||||
stw [r1 - 0x20], r10
|
||||
stw [r1 - 0x24], r11
|
||||
stw [r1 - 0x28], r12
|
||||
subi r6, r1, 0x40
|
||||
sub r6, r6, r4
|
||||
stw [r6], r1
|
||||
mr r1, r6
|
||||
|
||||
on_TObjectV8047c128_hp_change: # (TObjectV8047c128* this @ r3, int16_t amount @ r4, uint8_t flags @ r5)
|
||||
lhz r7, [r3 + 0x1C]
|
||||
cmplwi r7, 0x1000
|
||||
blt on_TObjectV8047c128_hp_change_skip_send
|
||||
cmplwi r7, 0x4000
|
||||
bge on_TObjectV8047c128_hp_change_skip_send
|
||||
rlwinm r6, r4, 14, 8, 15
|
||||
addis r6, r6, 1
|
||||
oris r6, r6, 0xFF00
|
||||
rlwinm r5, r5, 0, 16, 31
|
||||
or r5, r5, r6
|
||||
stw [r1 + 0x08], r5
|
||||
li r6, 0
|
||||
subi r3, r3, 4
|
||||
addi r7, r1, 0x08
|
||||
rlwinm r0, r4, 30, 24, 31
|
||||
mtctr r0
|
||||
copy_again:
|
||||
lwzu r0, [r3 + 4]
|
||||
stwu [r7 + 4], r0
|
||||
bdnz copy_again
|
||||
|
||||
mflr r0
|
||||
stw [r1 + 4], r0
|
||||
stwu [r1 - 0x20], r1
|
||||
stw [r1 + 0x08], r3
|
||||
stw [r1 + 0x0C], r4
|
||||
stw [r1 + 0x10], r5
|
||||
addi r3, r1, 0x08
|
||||
bl send_and_handle_60
|
||||
|
||||
mr r7, r3
|
||||
addi r3, r1, 0x10
|
||||
li r8, 0x1C
|
||||
lhbrx r6, [r7 + r8]
|
||||
oris r6, r6, 0xE403
|
||||
stw [r3], r6 # cmd.header
|
||||
andi. r0, r5, 1
|
||||
beq on_TObjectV8047c128_hp_change_skip_negate
|
||||
neg r4, r4
|
||||
on_TObjectV8047c128_hp_change_skip_negate:
|
||||
li r8, 4
|
||||
sthbrx [r3 + r8], r4 # cmd.hit_amount
|
||||
lhz r4, [r7 + 0x2E4]
|
||||
li r8, 6
|
||||
sthbrx [r3 + r8], r4 # cmd.total_damage_before_hit
|
||||
lhz r4, [r7 + 0x32C]
|
||||
li r8, 8
|
||||
sthbrx [r3 + r8], r4 # cmd.current_hp_before_hit
|
||||
lhz r4, [r7 + 0x2B8]
|
||||
li r8, 0x0A
|
||||
sthbrx [r3 + r8], r4 # cmd.max_hp
|
||||
|
||||
andi. r0, r5, 2
|
||||
bne on_TObjectV8047c128_hp_change_local_only
|
||||
bl send_and_handle_60
|
||||
b on_TObjectV8047c128_hp_change_send_done
|
||||
on_TObjectV8047c128_hp_change_local_only:
|
||||
bl on_6xE4
|
||||
on_TObjectV8047c128_hp_change_send_done:
|
||||
|
||||
lwz r3, [r1 + 0x08]
|
||||
lwz r4, [r1 + 0x0C]
|
||||
lwz r5, [r1 + 0x10]
|
||||
addi r1, r1, 0x20
|
||||
lwz r0, [r1 + 4]
|
||||
mtlr r0
|
||||
|
||||
on_TObjectV8047c128_hp_change_skip_send:
|
||||
andi. r0, r5, 1
|
||||
bne on_TObjectV8047c128_hp_change_b_to_add
|
||||
b TObjectV8047c128_subtract_hp
|
||||
on_TObjectV8047c128_hp_change_b_to_add:
|
||||
b TObjectV8047c128_add_hp
|
||||
lwz r1, [r1]
|
||||
lwz r3, [r1 - 0x04]
|
||||
lwz r4, [r1 - 0x08]
|
||||
lwz r5, [r1 - 0x0C]
|
||||
lwz r6, [r1 - 0x10]
|
||||
lwz r7, [r1 - 0x14]
|
||||
lwz r8, [r1 - 0x18]
|
||||
lwz r9, [r1 - 0x1C]
|
||||
lwz r10, [r1 - 0x20]
|
||||
lwz r11, [r1 - 0x24]
|
||||
lwz r12, [r1 - 0x28]
|
||||
lwz r0, [r1 + 0x04]
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="DMC"
|
||||
.meta description="Mitigates effects\nof enemy health\ndesync"
|
||||
|
||||
.versions 4OJB 4OJD 4OJU 4OED 4OEU 4OPD 4OPU
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
write_call_to_code_multi:
|
||||
.include WriteCallToCodeMultiXB
|
||||
|
||||
|
||||
|
||||
start:
|
||||
call write_static_patches
|
||||
call write_incr_hp_with_sync
|
||||
ret
|
||||
|
||||
|
||||
|
||||
# Write TObjectV004434c8::incr_hp_with_sync
|
||||
write_incr_hp_with_sync:
|
||||
push 5
|
||||
push <VERS 0x002A60CF 0x002A6BAF 0x002A807F 0x002A7B0F 0x002A7CEF 0x002A7B2F 0x002A7DAF> # v17 inlined callsite + 5
|
||||
push 5
|
||||
push <VERS 0x002A808D 0x002A8B6D 0x002AA03D 0x002A9ACD 0x002A9CAD 0x002A9AED 0x002A9D6D> # TObjectV004434c8::subtract_hp_if_not_in_state_2 + D
|
||||
push 5
|
||||
push <VERS 0x002A68FB 0x002A73DB 0x002A88AB 0x002A833B 0x002A851B 0x002A835B 0x002A85DB> # TObjectV004434c8::v18_accept_hit (presumably Resta) - this is add_hp, not subtract_hp!
|
||||
push 5
|
||||
push <VERS 0x002A650D 0x002A6FED 0x002A84BD 0x002A7F4D 0x002A812D 0x002A7F6D 0x002A81ED> # TObjectV004434c8::v18_accept_hit cases 0 and 4
|
||||
push 5
|
||||
push <VERS 0x002A65BA 0x002A709A 0x002A856A 0x002A7FFA 0x002A81DA 0x002A801A 0x002A829A> # TObjectV004434c8::v18_accept_hit case 1
|
||||
push 5
|
||||
push <VERS 0x002A6670 0x002A7150 0x002A8620 0x002A80B0 0x002A8290 0x002A80D0 0x002A8350> # TObjectV004434c8::v18_accept_hit case 2
|
||||
push 5
|
||||
push <VERS 0x002A6769 0x002A7249 0x002A8719 0x002A81A9 0x002A8389 0x002A81C9 0x002A8449> # TObjectV004434c8::v18_accept_hit case 3
|
||||
push 5
|
||||
push <VERS 0x002A6C19 0x002A76F9 0x002A8BC9 0x002A8659 0x002A8839 0x002A8679 0x002A88F9> # TObjectV004434c8::v18_accept_hit case 0x13
|
||||
push 5
|
||||
push <VERS 0x002A6CAC 0x002A778C 0x002A8C5C 0x002A86EC 0x002A88CC 0x002A870C 0x002A898C> # TObjectV004434c8::v18_accept_hit case 0x15
|
||||
push 5
|
||||
push <VERS 0x002A70AE 0x002A7B92 0x002A9062 0x002A8AF2 0x002A8CD2 0x002A8B12 0x002A8D92> # TObjectV004434c8::v19_handle_hit_special_effects case 1
|
||||
push 5
|
||||
push <VERS 0x002A7A53 0x002A7BD3 0x002A90A3 0x002A8B33 0x002A8D13 0x002A8B53 0x002A8DD3> # TObjectV004434c8::v19_handle_hit_special_effects case 1
|
||||
push 5
|
||||
push <VERS 0x002A76C4 0x002A81A8 0x002A9678 0x002A9108 0x002A92E8 0x002A9128 0x002A93A8> # TObjectV004434c8::v19_handle_hit_special_effects case 6
|
||||
push 5
|
||||
push <VERS 0x002A7953 0x002A8437 0x002A9907 0x002A9397 0x002A9577 0x002A93B7 0x002A9637> # TObjectV004434c8::v19_handle_hit_special_effects case 9
|
||||
push 5
|
||||
push <VERS 0x0024A140 0x002A8530 0x002A9A00 0x002A9490 0x002A9670 0x002A94B0 0x002A9730> # TObjectV004434c8::v19_handle_hit_special_effects case 0x0A
|
||||
push 5
|
||||
push <VERS 0x002A7CDB 0x002A87BF 0x002A9C8F 0x002A971F 0x002A98FF 0x002A973F 0x002A99BF> # TObjectV004434c8::v19_handle_hit_special_effects case 0x0D
|
||||
push 15
|
||||
call +4
|
||||
.deltaof on_add_or_subtract_hp_start, on_add_or_subtract_hp_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call on_add_or_subtract_hp_end
|
||||
|
||||
on_add_or_subtract_hp_start: # (TObjectV004434c8* this @ eax, int16_t amount @ cx) -> bool @ eax
|
||||
# Check if callsite is subtract_hp_if_not_in_state_2
|
||||
|
||||
push eax
|
||||
push ecx
|
||||
push ebx
|
||||
movzx edx, word [eax + 0x1C] # ene->entity_id
|
||||
cmp edx, 0x1000
|
||||
jl on_add_or_subtract_hp_skip_send
|
||||
cmp edx, 0x1B50
|
||||
jge on_add_or_subtract_hp_skip_send
|
||||
|
||||
and edx, 0x0FFF
|
||||
imul edx, edx, 0x0C
|
||||
add edx, [<VERS 0x00633068 0x006336C8 0x0063B210 0x006386F8 0x00637F90 0x006386F8 0x00638A90>] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
sub esp, 0x0C
|
||||
mov word [esp], 0x03E4
|
||||
mov bx, [eax + 0x1C]
|
||||
mov [esp + 0x02], bx # cmd.entity_id
|
||||
cmp dword [esp + 0x18], <VERS 0x002A6900 0x002A73E0 0x002A88B0 0x002A8340 0x002A8520 0x002A8360 0x002A85E0> # Check if callsite is add_hp
|
||||
jne on_add_or_subtract_hp_skip_negate_amount
|
||||
neg cx
|
||||
on_add_or_subtract_hp_skip_negate_amount:
|
||||
mov [esp + 0x04], cx # cmd.hit_amount
|
||||
mov bx, [edx + 6]
|
||||
mov [esp + 0x06], bx # cmd.total_damage_before_hit
|
||||
mov bx, [eax + 0x0330]
|
||||
mov [esp + 0x08], bx # cmd.current_hp
|
||||
mov bx, [eax + 0x02BC]
|
||||
mov [esp + 0x0A], bx # cmd.max_hp
|
||||
|
||||
mov ecx, esp
|
||||
mov ebx, [<VERS 0x0071EEFC 0x0071F55C 0x007270A0 0x0072459C 0x00723E20 0x0072459C 0x00724920>] # root_protocol
|
||||
test ebx, ebx
|
||||
jz on_add_or_subtract_hp_skip_send
|
||||
mov eax, 0x0C
|
||||
# Can't just `call <addr>` here because this code is relocated at apply time
|
||||
mov edx, <VERS 0x002DA120 0x002DACF0 0x002DC5B0 0x002DC080 0x002DC580 0x002DC0B0 0x002DC600>
|
||||
call edx # send_60(root_protocol, &out_cmd, sizeof(out_cmd))
|
||||
add esp, 0x0C
|
||||
|
||||
on_add_or_subtract_hp_skip_send:
|
||||
mov edx, <VERS 0x002A80C0 0x002A8BA0 0x002AA070 0x002A9B00 0x002A9CE0 0x002A9B20 0x002A9DA0> # subtract_hp
|
||||
mov eax, <VERS 0x002A80F0 0x002A8BD0 0x002AA0A0 0x002A9B30 0x002A9D10 0x002A9B50 0x002A9DD0> # add_hp
|
||||
cmp dword [esp + 0x0C], <VERS 0x002A6900 0x002A73E0 0x002A88B0 0x002A8340 0x002A8520 0x002A8360 0x002A85E0> # Check if callsite is add_hp
|
||||
cmove edx, eax
|
||||
pop ebx
|
||||
pop ecx
|
||||
pop eax
|
||||
jmp edx
|
||||
|
||||
on_add_or_subtract_hp_end:
|
||||
call write_call_to_code_multi
|
||||
ret
|
||||
|
||||
|
||||
|
||||
write_static_patches:
|
||||
.include WriteCodeBlocksXB
|
||||
|
||||
# Don't let 6x0A handler overwrite total_damage
|
||||
.data <VERS 0x002B3B55 0x002B4625 0x002B5BB5 0x002B56C5 0x002B58A5 0x002B56E5 0x002B59B5>
|
||||
.data 5
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
.data <VERS 0x00537180 0x00537800 0x0053EB20 0x0053BFA0 0x0053B840 0x0053BFA0 0x0053C340>
|
||||
.data 8
|
||||
.data 0x000600E4 # subcommand=0xE4, flags=6
|
||||
.addrof handle_6xE4
|
||||
|
||||
.data <VERS 0x002DA510 0x002DB0E0 0x002DC9A0 0x002DC470 0x002DC970 0x002DC4A0 0x002DC9F0>
|
||||
.deltaof handle_91_replacement, handle_6xE4_end
|
||||
.address <VERS 0x002DA510 0x002DB0E0 0x002DC9A0 0x002DC470 0x002DC970 0x002DC4A0 0x002DC9F0>
|
||||
handle_91_replacement: # [std] (S_91* cmd @ [esp + 4]) -> void
|
||||
ret 4
|
||||
handle_6xE4: # [std] (G_6xE4* cmd @ [esp + 4]) -> void
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
mov ebx, [esp + 0x10] # cmd
|
||||
movzx eax, word [ebx + 2]
|
||||
cmp eax, 0x1000
|
||||
jl handle_6xE4_return
|
||||
cmp eax, 0x1B50
|
||||
jge handle_6xE4_return
|
||||
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [<VERS 0x00633068 0x006336C8 0x0063B210 0x006386F8 0x00637F90 0x006386F8 0x00638A90>] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
movzx edx, word [eax + 0x06] # st.total_damage
|
||||
movsx esi, word [ebx + 0x04] # cmd->hit_amount
|
||||
movzx edi, word [ebx + 0x0A] # cmd->max_hp
|
||||
add edx, esi # st.total_damage + cmd->hit_amount
|
||||
cmp edx, edi
|
||||
jl handle_6xE4_damage_less_than_max_hp
|
||||
mov [eax + 0x06], di # st.total_damage = cmd->max_hp;
|
||||
mov edx, [eax]
|
||||
test edx, 0x800
|
||||
jnz handle_6xE4_return
|
||||
or edx, 0x800
|
||||
mov [eax], edx
|
||||
push edx # out_cmd.flags
|
||||
sub esp, 8
|
||||
mov word [esp], 0x030A # out_cmd.header.{subcommand,size}
|
||||
mov si, [ebx + 2]
|
||||
mov [esp + 2], si # out_cmd.header.entity_id
|
||||
and si, 0x0FFF
|
||||
mov [esp + 4], si # out_cmd.entity_index
|
||||
mov [esp + 6], di # out_cmd.total_damage
|
||||
|
||||
mov ecx, esp
|
||||
push ecx # For handle_60 later
|
||||
mov ebx, [<VERS 0x0071EEFC 0x0071F55C 0x007270A0 0x0072459C 0x00723E20 0x0072459C 0x00724920>] # root_protocol
|
||||
test ebx, ebx
|
||||
jz handle_6xE4_root_protocol_missing
|
||||
mov eax, 0x0C
|
||||
call <VERS 0x002DA120 0x002DACF0 0x002DC5B0 0x002DC080 0x002DC580 0x002DC0B0 0x002DC600> # send_60(root_protocol, &out_cmd, sizeof(out_cmd))
|
||||
handle_6xE4_root_protocol_missing:
|
||||
mov dword [<VERS 0x0071E8C8 0x0071EF28 0x00726A68 0x00723F68 0x007237E8 0x00723F68 0x007242E8>], 1
|
||||
call <VERS 0x002DBC30 0x002DC7B0 0x002DE070 0x002DDB90 0x002DE090 0x002DDBC0 0x002DE0C0> # handle_60(&out_cmd)
|
||||
mov dword [<VERS 0x0071E8C8 0x0071EF28 0x00726A68 0x00723F68 0x007237E8 0x00723F68 0x007242E8>], 0
|
||||
|
||||
add esp, 0x10
|
||||
jmp handle_6xE4_return
|
||||
|
||||
handle_6xE4_damage_less_than_max_hp:
|
||||
xor edi, edi
|
||||
cmp edx, edx
|
||||
cmovl edx, edi
|
||||
mov [eax + 0x06], dx # st.total_damage = std::max<int16_t>(st.total_damage + cmd->hit_amount, 0);
|
||||
|
||||
mov esi, eax # esi = ene_st
|
||||
movzx di, word [ebx + 2]
|
||||
call <VERS 0x002B36B0 0x002B4180 0x002B5710 0x002B5220 0x002B5400 0x002B5240 0x002B5510> # auto* ene = get_enemy_entity(cmd->header.entity_id);
|
||||
test eax, eax
|
||||
jz handle_6xE4_return
|
||||
mov ecx, eax
|
||||
push esi
|
||||
mov edx, [ecx]
|
||||
call [edx + 0x138] # ene->vtable[0x4E](ene, &st);
|
||||
|
||||
handle_6xE4_return:
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
handle_6xE4_end:
|
||||
|
||||
|
||||
|
||||
# Rewrite TObjectV004434c8::subtract_hp_if_not_in_state_2
|
||||
.data <VERS 0x002A8080 0x002A8B60 0x002AA030 0x002A9AC0 0x002A9CA0 0x002A9AE0 0x002A9D60>
|
||||
.deltaof on_subtract_hp_if_not_in_state_2_start, on_subtract_hp_if_not_in_state_2_end
|
||||
.address <VERS 0x002A8080 0x002A8B60 0x002AA030 0x002A9AC0 0x002A9CA0 0x002A9AE0 0x002A9D60>
|
||||
on_subtract_hp_if_not_in_state_2_start: # (TObjectV004434c8* this @ eax, int16_t amount @ cx) -> bool @ eax
|
||||
cmp word [eax + 0x328], 2
|
||||
jne on_subtract_hp_if_not_in_state_2_do_subtract
|
||||
xor eax, eax
|
||||
ret
|
||||
on_subtract_hp_if_not_in_state_2_do_subtract:
|
||||
call -1 # Overwritten by write_call_to_code_multi later
|
||||
ret
|
||||
on_subtract_hp_if_not_in_state_2_end:
|
||||
|
||||
|
||||
|
||||
# Inlined callsite of subtract_hp in TObjectV004434c8::v17
|
||||
.data <VERS 0x002A60CA 0x002A6BAA 0x002A807A 0x002A7B0A 0x002A7CEA 0x002A7B2A 0x002A7DAA>
|
||||
.deltaof v17_subtract_hp_inlined_callsite_start, v17_subtract_hp_inlined_callsite_end
|
||||
.address <VERS 0x002A60CA 0x002A6BAA 0x002A807A 0x002A7B0A 0x002A7CEA 0x002A7B2A 0x002A7DAA>
|
||||
v17_subtract_hp_inlined_callsite_start:
|
||||
# This must assemble to exactly 0x1A bytes. There is a vfn call shortly after
|
||||
# this, and fortunately it appears eax, ecx, and edx are not used before
|
||||
# then, so we don't have to save any registers here; we just have to move the
|
||||
# args into the right places.
|
||||
mov cx, ax
|
||||
mov eax, edi
|
||||
call -1 # Overwritten by write_call_to_code_multi later
|
||||
jmp v17_subtract_hp_inlined_callsite_end
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
int 3
|
||||
v17_subtract_hp_inlined_callsite_end:
|
||||
|
||||
|
||||
|
||||
.data 0x00000000
|
||||
.data 0x00000000
|
||||
@@ -13,100 +13,88 @@ write_address_of_code:
|
||||
|
||||
start:
|
||||
|
||||
# Change class_flags check to read only low 16 bits
|
||||
# This is annoying since the opcode we need is one byte longer than the
|
||||
# original, so we have to write a call to allocated code here, sigh
|
||||
push 6
|
||||
push 0x00773448
|
||||
push 1
|
||||
call +4
|
||||
.deltaof class_flags_check_start, class_flags_check_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call class_flags_check_end
|
||||
class_flags_check_start:
|
||||
movzx eax, word [esi + 0x2E8]
|
||||
ret
|
||||
class_flags_check_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Replace 6x09 with 6xE4 in subcommand handler table
|
||||
mov dword [0x00A0FC30], 0x000600E4 # subcommand=0xE4, flags=6
|
||||
push 0x00A0FC34
|
||||
call +4
|
||||
.deltaof on_6xE4_start, on_6xE4_end
|
||||
.deltaof handle_6xE4_start, handle_6xE4_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call on_6xE4_end
|
||||
on_6xE4_start: # (G_6xE4* cmd @ [esp + 4])
|
||||
mov edx, [esp + 4]
|
||||
movzx eax, word [edx + 2]
|
||||
.include GetEnemyEntity-59NL # eax = get_enemy_entity(cmd->header.entity_id)
|
||||
call handle_6xE4_end
|
||||
|
||||
handle_6xE4_start: # (G_6xE4* cmd @ [esp + 4]) -> void
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
mov ebx, [esp + 0x10] # cmd
|
||||
movzx eax, word [ebx + 2]
|
||||
cmp eax, 0x1000
|
||||
jl handle_6xE4_return
|
||||
cmp eax, 0x1B50
|
||||
jge handle_6xE4_return
|
||||
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [0x00AB02B8] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
movzx edx, word [eax + 0x06] # st.total_damage
|
||||
movsx esi, word [ebx + 0x04] # cmd->hit_amount
|
||||
movzx edi, word [ebx + 0x0A] # cmd->max_hp
|
||||
add edx, esi # st.total_damage + cmd->hit_amount
|
||||
cmp edx, edi
|
||||
jl handle_6xE4_damage_less_than_max_hp
|
||||
mov [eax + 0x06], di # st.total_damage = cmd->max_hp;
|
||||
mov edx, [eax]
|
||||
test edx, 0x800
|
||||
jnz handle_6xE4_return
|
||||
or edx, 0x800
|
||||
mov [eax], edx
|
||||
push edx # out_cmd.flags
|
||||
sub esp, 8
|
||||
mov word [esp], 0x030A # out_cmd.header.{subcommand,size}
|
||||
mov si, [ebx + 2]
|
||||
mov [esp + 2], si # out_cmd.header.entity_id
|
||||
and si, 0x0FFF
|
||||
mov [esp + 4], si # out_cmd.entity_index
|
||||
mov [esp + 6], di # out_cmd.total_damage
|
||||
mov ecx, esp
|
||||
mov edx, 0x008003E0
|
||||
call edx # send_and_handle_60(&out_cmd);
|
||||
add esp, 0x0C
|
||||
jmp handle_6xE4_return
|
||||
|
||||
handle_6xE4_damage_less_than_max_hp:
|
||||
xor edi, edi
|
||||
cmp edx, edx
|
||||
cmovl edx, edi
|
||||
mov [eax + 0x06], dx # st.total_damage = std::max<int16_t>(st.total_damage + cmd->hit_amount, 0);
|
||||
|
||||
mov edx, eax # edx = ene_st
|
||||
movzx eax, word [ebx + 2]
|
||||
.include GetEnemyEntity-59NL # auto* ene = get_enemy_entity(cmd->header.entity_id);
|
||||
test eax, eax
|
||||
je on_6xE4_no_entity
|
||||
movzx ecx, word [eax + 0x2EA]
|
||||
movzx edx, word [edx + 4]
|
||||
add ecx, edx
|
||||
xor edx, edx
|
||||
cmp ecx, 0
|
||||
cmovl ecx, edx
|
||||
movzx edx, word [eax + 0x2BC]
|
||||
cmp ecx, edx
|
||||
cmovg ecx, edx
|
||||
mov [eax + 0x2EA], cx
|
||||
on_6xE4_no_entity:
|
||||
jz handle_6xE4_return
|
||||
mov ecx, eax
|
||||
push edx
|
||||
mov edx, [ecx]
|
||||
call [edx + 0x148] # ene->vtable[0x52](ene, &st);
|
||||
|
||||
handle_6xE4_return:
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
on_6xE4_end:
|
||||
|
||||
handle_6xE4_end:
|
||||
call write_address_of_code
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::add_hp_with_sync
|
||||
# Write TObjectV00b441c0::incr_hp_with_sync
|
||||
push 5
|
||||
push 0x00774448 # TObjectV00b441c0::v18_accept_hit (presumably Resta)
|
||||
push 1
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_add_hp_with_sync_start, TObjectV00b441c0_add_hp_with_sync_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_add_hp_with_sync_end
|
||||
TObjectV00b441c0_add_hp_with_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
mov ax, [ecx + 0x1C]
|
||||
cmp ax, 0x1000
|
||||
jl TObjectV00b441c0_add_hp_with_sync_skip_send
|
||||
cmp ax, 0x4000
|
||||
jge TObjectV00b441c0_add_hp_with_sync_skip_send
|
||||
sub esp, 0x0C
|
||||
mov word [esp], 0x03E4
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov ax, [esp + 0x10]
|
||||
neg ax
|
||||
mov [esp + 0x04], ax # cmd.hit_amount = -amount
|
||||
mov ax, [ecx + 0x2EA]
|
||||
mov [esp + 0x06], ax # cmd.total_damage_before_hit = this->total_damage
|
||||
mov ax, [ecx + 0x334]
|
||||
mov [esp + 0x08], ax # cmd.current_hp_before_hit = this->current_hp
|
||||
mov ax, [ecx + 0x2BC]
|
||||
mov [esp + 0x0A], ax # cmd.max_hp = this->max_hp
|
||||
push ecx
|
||||
lea ecx, [esp + 4]
|
||||
mov eax, 0x008003E0
|
||||
call eax # send_and_handle_60(void* data @ ecx)
|
||||
pop ecx
|
||||
add esp, 0x0C
|
||||
TObjectV00b441c0_add_hp_with_sync_skip_send:
|
||||
mov eax, 0x007773D4 # TObjectV00b441c0::add_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_add_hp_with_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::subtract_hp_with_sync
|
||||
push 0x00774448 # TObjectV00b441c0::v18_accept_hit (presumably Resta) - this is add_hp, not subtract_hp!
|
||||
push 5
|
||||
push 0x00777287 # TObjectV00b441c0::subtract_hp_if_in_state_2
|
||||
push 0x00777287 # TObjectV00b441c0::subtract_hp_if_not_in_state_2
|
||||
push 5
|
||||
push 0x00776CD6 # TObjectV00b441c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
@@ -139,147 +127,66 @@ TObjectV00b441c0_add_hp_with_sync_end:
|
||||
push 0x00773EFA # TObjectV00b441c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00773937 # TObjectV00b441c0::v17
|
||||
push 17
|
||||
push 18
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_subtract_hp_with_sync_start, TObjectV00b441c0_subtract_hp_with_sync_end
|
||||
.deltaof on_add_or_subtract_hp_start, on_add_or_subtract_hp_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_subtract_hp_with_sync_end
|
||||
TObjectV00b441c0_subtract_hp_with_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
mov ax, [ecx + 0x1C]
|
||||
cmp ax, 0x1000
|
||||
jl TObjectV00b441c0_subtract_hp_with_sync_skip_send
|
||||
cmp ax, 0x4000
|
||||
jge TObjectV00b441c0_subtract_hp_with_sync_skip_send
|
||||
call on_add_or_subtract_hp_end
|
||||
|
||||
on_add_or_subtract_hp_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
movzx eax, word [ecx + 0x1C] # ene->entity_id
|
||||
cmp eax, 0x1000
|
||||
jl on_add_or_subtract_hp_skip_send
|
||||
cmp eax, 0x1B50
|
||||
jge on_add_or_subtract_hp_skip_send
|
||||
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [0x00AB02B8] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
sub esp, 0x0C
|
||||
mov word [esp], 0x03E4
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov ax, [esp + 0x10]
|
||||
mov [esp + 0x04], ax # cmd.hit_amount = amount
|
||||
mov ax, [ecx + 0x2EA]
|
||||
mov [esp + 0x06], ax # cmd.total_damage_before_hit = this->total_damage
|
||||
mov ax, [ecx + 0x334]
|
||||
mov [esp + 0x08], ax # cmd.current_hp_before_hit = this->current_hp
|
||||
mov ax, [ecx + 0x2BC]
|
||||
mov [esp + 0x0A], ax # cmd.max_hp = this->max_hp
|
||||
mov dx, [ecx + 0x1C]
|
||||
mov [esp + 0x02], dx # cmd.entity_id
|
||||
mov dx, [esp + 0x10]
|
||||
cmp dword [esp + 0x0C], 0x0077444D # Check if callsite is add_hp
|
||||
jne on_add_or_subtract_hp_skip_negate_amount
|
||||
neg dx
|
||||
on_add_or_subtract_hp_skip_negate_amount:
|
||||
mov [esp + 0x04], dx # cmd.hit_amount
|
||||
mov dx, [eax + 6]
|
||||
mov [esp + 0x06], dx # cmd.total_damage_before_hit
|
||||
mov dx, [ecx + 0x0334]
|
||||
mov [esp + 0x08], dx # cmd.current_hp
|
||||
mov dx, [ecx + 0x02BC]
|
||||
mov [esp + 0x0A], dx # cmd.max_hp
|
||||
mov edx, esp
|
||||
push ecx
|
||||
lea ecx, [esp + 4]
|
||||
mov eax, 0x008003E0
|
||||
call eax # send_and_handle_60(void* data @ ecx)
|
||||
pop ecx
|
||||
add esp, 0x0C
|
||||
TObjectV00b441c0_subtract_hp_with_sync_skip_send:
|
||||
mov eax, 0x00777414 # TObjectV00b441c0::subtract_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_subtract_hp_with_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::subtract_hp_without_sync
|
||||
push 5
|
||||
push 0x00777CBD # TObjectV00b441c0::v25_give_poison_damage
|
||||
push 1
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_subtract_hp_without_sync_start, TObjectV00b441c0_subtract_hp_without_sync_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_subtract_hp_without_sync_end
|
||||
TObjectV00b441c0_subtract_hp_without_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
movzx edx, word [ecx + 0x2EA]
|
||||
movsx eax, word [esp + 2]
|
||||
add edx, eax
|
||||
movzx eax, word [ecx + 0x2BC]
|
||||
cmp edx, eax
|
||||
cmovg edx, eax
|
||||
mov [ecx + 0x2EA], dx
|
||||
mov eax, 0x00777414 # TObjectV00b441c0::subtract_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_subtract_hp_without_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write handle_6x0A_update_total_damage_hook
|
||||
push 5
|
||||
push 0x0078781F
|
||||
push 1
|
||||
call +4
|
||||
.deltaof handle_6x0A_update_total_damage_hook_start, handle_6x0A_update_total_damage_hook_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call handle_6x0A_update_total_damage_hook_end
|
||||
handle_6x0A_update_total_damage_hook_start: # (G_6x0A* cmd @ eax, int16_t cmd_total_damage @ cx) -> void
|
||||
# Nonstandard calling convention:
|
||||
# Caller-save: ecx, ebx
|
||||
# Callee-save: eax, edx, ebp, esi, edi
|
||||
push eax
|
||||
movzx eax, word [eax + 2]
|
||||
.include GetEnemyEntity-59NL # eax = get_enemy_entity(cmd->header.entity_id)
|
||||
test eax, eax
|
||||
jz handle_6x0A_update_total_damage_hook_no_entity
|
||||
mov ebx, [eax + 0x2EA]
|
||||
cmp ecx, ebx
|
||||
cmovl ecx, ebx
|
||||
mov ebx, [eax + 0x2BC]
|
||||
cmp ecx, ebx
|
||||
cmovg ecx, ebx
|
||||
handle_6x0A_update_total_damage_hook_no_entity:
|
||||
mov [esp + 0x0E], cx # ene_st.total_damage = cx
|
||||
pop eax
|
||||
ret
|
||||
handle_6x0A_update_total_damage_hook_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write handle_6x0A_call_object_update_vfn
|
||||
push 6
|
||||
push 0x007878CC
|
||||
push 1
|
||||
call +4
|
||||
.deltaof handle_6x0A_call_object_update_vfn_start, handle_6x0A_call_object_update_vfn_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call handle_6x0A_call_object_update_vfn_end
|
||||
handle_6x0A_call_object_update_vfn_start: # (TObjectV00b441c0* this @ ecx, EnemyState* ene_st @ [esp + 4]) -> void
|
||||
# Standard calling conventions
|
||||
push dword [edx + 0x148] # vfn to call at end (which we do via ret)
|
||||
push ecx
|
||||
test dword [ecx + 0x30], 0x800 # this->game_flags & 0x800
|
||||
jnz handle_6x0A_call_object_update_vfn_tail_call
|
||||
mov edx, [esp + 0x0C]
|
||||
test dword [edx], 0x800 # ene_st->flags & 0x800
|
||||
jnz handle_6x0A_call_object_update_vfn_tail_call
|
||||
mov ax, [edx + 6]
|
||||
cmp ax, [ecx + 0x2BC] # ene_st->total_damage >= ene->max_hp
|
||||
jl handle_6x0A_call_object_update_vfn_tail_call
|
||||
or dword [edx], 0x800 # ene_st->game_flags |= 0x800 (set dead flag)
|
||||
mov eax, [0x00AAB284]
|
||||
test eax, eax
|
||||
jz handle_6x0A_call_object_update_vfn_tail_call
|
||||
push dword [edx] # cmd.game_flags = ene_st->game_flags
|
||||
sub esp, 8
|
||||
mov ax, [edx + 6]
|
||||
mov [esp + 0x06], ax # cmd.total_damage = ene_st->total_damage
|
||||
mov ax, [ecx + 0x2C]
|
||||
mov [esp + 0x04], ax # cmd.enemy_index = this->enemy_index
|
||||
mov ax, [ecx + 0x1C]
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov word [esp], 0x030A # cmd.header.subommand = 0x0A, cmd.header.size = 0x03
|
||||
push 0x0C
|
||||
lea ecx, [esp + 4]
|
||||
push ecx
|
||||
push edx
|
||||
mov ecx, [0x00AAB284]
|
||||
mov eax, 0x007D3F38
|
||||
call eax # send_60(TGameProtocol* this @ ecx, void* data @ [esp + 4], uint32_t size @ [esp + 8])
|
||||
add esp, 0x0C
|
||||
handle_6x0A_call_object_update_vfn_tail_call:
|
||||
mov edx, 0x007D3F38
|
||||
call edx # send_60(root_protocol, &cmd, sizeof(cmd));
|
||||
pop ecx
|
||||
ret
|
||||
handle_6x0A_call_object_update_vfn_end:
|
||||
add esp, 0x0C
|
||||
|
||||
on_add_or_subtract_hp_skip_send:
|
||||
mov eax, 0x00777414 # subtract_hp
|
||||
mov edx, 0x007773D4 # add_hp
|
||||
cmp dword [esp], 0x0077444D # Check if callsite is add_hp
|
||||
cmove eax, edx
|
||||
jmp eax
|
||||
|
||||
on_add_or_subtract_hp_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Don't let 6x0A handler overwrite total_damage
|
||||
mov byte [0x0078781F], 0x90
|
||||
mov dword [0x00787820], 0x90909090
|
||||
|
||||
|
||||
|
||||
ret
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# Returns the client specific_version in eax and the address of the
|
||||
# MmSetAddressProtect function pointer in edx, which is immediately followed by
|
||||
# the MmQueryAddressProtect function pointer.
|
||||
|
||||
start:
|
||||
mov ecx, 0x61657244
|
||||
|
||||
# JP beta
|
||||
mov eax, 0x344F4A42
|
||||
mov edx, 0x00400578
|
||||
cmp [0x0043D460], ecx
|
||||
je done
|
||||
|
||||
# JP disc
|
||||
mov eax, 0x344F4A44
|
||||
mov edx, 0x00400918
|
||||
cmp [0x0043D7D0], ecx
|
||||
je done
|
||||
|
||||
# JP title update
|
||||
mov eax, 0x344F4A55
|
||||
mov edx, 0x00403E3C
|
||||
cmp [0x00440FE0], ecx
|
||||
je done
|
||||
|
||||
# US disc
|
||||
mov eax, 0x344F4544
|
||||
mov edx, 0x00404518
|
||||
cmp [0x0044174C], ecx
|
||||
je done
|
||||
|
||||
# US title update
|
||||
mov eax, 0x344F4555
|
||||
mov edx, 0x00403E3C
|
||||
cmp [0x00440FEC], ecx
|
||||
je done
|
||||
|
||||
# EU disc
|
||||
mov eax, 0x344F5044
|
||||
mov edx, 0x00404538
|
||||
cmp [0x00441768], ecx
|
||||
je done
|
||||
|
||||
# EU title update
|
||||
mov eax, 0x344F5055
|
||||
mov edx, 0x0040491C
|
||||
cmp [0x00441AF8], ecx
|
||||
je done
|
||||
|
||||
# Unknown version
|
||||
mov eax, 0x344F0000
|
||||
xor edx, edx
|
||||
|
||||
done:
|
||||
@@ -14,5 +14,13 @@ reloc0:
|
||||
.offsetof start
|
||||
|
||||
start:
|
||||
.include VersionDetectWithPatchFunctionsXB
|
||||
.include GetVersionInfoXB
|
||||
|
||||
test eax, eax
|
||||
jz version_not_found
|
||||
mov eax, [eax]
|
||||
ret
|
||||
|
||||
version_not_found:
|
||||
mov eax, 0x344F0000
|
||||
ret
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# This file defines the following function:
|
||||
# write_call_to_code(
|
||||
# const void* patch_code,
|
||||
# size_t patch_code_size,
|
||||
# size_t call_count,
|
||||
# void* call_opcode_address,
|
||||
# ssize_t call_opcode_bytes,
|
||||
# void [/std] write_call_to_code(
|
||||
# const void* patch_code @ [esp + 0x04],
|
||||
# size_t patch_code_size @ [esp + 0x08],
|
||||
# size_t call_count @ [esp + 0x0C],
|
||||
# void* call_opcode_address @ [esp + 0x10],
|
||||
# ssize_t call_opcode_bytes @ [esp + 0x14],
|
||||
# ...);
|
||||
# This function allocates memory for patch_code, copies patch_code to that
|
||||
# memory, then writes a call or jmp opcode to call_opcode_address that calls
|
||||
|
||||
@@ -1,56 +1,57 @@
|
||||
start:
|
||||
.include VersionDetectWithPatchFunctionsXB
|
||||
|
||||
xor eax, eax
|
||||
cmp edx, 0
|
||||
jne can_patch
|
||||
.include GetVersionInfoXB
|
||||
test eax, eax
|
||||
jnz can_patch
|
||||
ret
|
||||
can_patch:
|
||||
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
mov edi, edx # edi = ptr to useful kernel function ptrs
|
||||
jmp get_patch_data_ptr
|
||||
can_patch:
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
mov edi, eax # edi = ptr to version info struct
|
||||
jmp get_patch_data_ptr
|
||||
get_patch_data_ptr_ret:
|
||||
pop ebx # ebx = patch header
|
||||
pop ebx # ebx = patch header
|
||||
|
||||
apply_next_patch:
|
||||
cmp dword [ebx + 4], 0
|
||||
jne copy_code_and_apply_again
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax, 1
|
||||
cmp dword [ebx + 4], 0
|
||||
jne copy_code_and_apply_again
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax, 1
|
||||
ret
|
||||
|
||||
copy_code_and_apply_again:
|
||||
push dword [ebx] # dest addr
|
||||
call [edi + 4] # MmQueryAddressProtect
|
||||
mov esi, eax # esi = prev protection flags
|
||||
push dword [ebx] # dest addr
|
||||
mov ecx, [edi + 0x0C]
|
||||
call [ecx] # MmQueryAddressProtect
|
||||
mov esi, eax # esi = prev protection flags
|
||||
|
||||
push 4 # new protection flags
|
||||
push dword [ebx + 4] # size
|
||||
push dword [ebx] # base address
|
||||
call [edi] # MmSetAddressProtect
|
||||
push 4 # new protection flags
|
||||
push dword [ebx + 4] # size
|
||||
push dword [ebx] # base address
|
||||
mov ecx, [edi + 0x08]
|
||||
call [ecx] # MmSetAddressProtect
|
||||
|
||||
xor ecx, ecx # ecx = offset
|
||||
mov edx, [ebx] # edx = dest addr
|
||||
xor ecx, ecx # ecx = offset
|
||||
mov edx, [ebx] # edx = dest addr
|
||||
copy_next_byte:
|
||||
mov al, [ebx + ecx + 8] # copy one byte to dest
|
||||
mov [edx + ecx], al
|
||||
inc ecx # offset++
|
||||
cmp [ebx + 4], ecx # check if all bytes have been copied
|
||||
jne copy_next_byte
|
||||
mov al, [ebx + ecx + 8] # copy one byte to dest
|
||||
mov [edx + ecx], al
|
||||
inc ecx # offset++
|
||||
cmp [ebx + 4], ecx # check if all bytes have been copied
|
||||
jne copy_next_byte
|
||||
|
||||
push esi # new protection flags
|
||||
push dword [ebx + 4] # size
|
||||
push dword [ebx] # base address
|
||||
lea ebx, [ebx + ecx + 8] # advance to next block
|
||||
call [edi] # MmSetAddressProtect
|
||||
jmp apply_next_patch
|
||||
push esi # new protection flags
|
||||
push dword [ebx + 4] # size
|
||||
push dword [ebx] # base address
|
||||
lea ebx, [ebx + ecx + 8] # advance to next block
|
||||
mov ecx, [edi + 0x08]
|
||||
call [ecx] # MmSetAddressProtect
|
||||
jmp apply_next_patch
|
||||
|
||||
get_patch_data_ptr:
|
||||
call get_patch_data_ptr_ret
|
||||
call get_patch_data_ptr_ret
|
||||
|
||||
first_patch_header:
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
Used regions in PSO GC:
|
||||
|
||||
80004000-80004194 (0194) ExtendedItemInfo (AR code uses 80005000 due to conflict with q8853x)
|
||||
800041A0-800041B8 (0018) UnsellableRares
|
||||
800041C0-???????? (????) EnemyDamageSync
|
||||
800041C0-???????? (TODO) EnemyDamageSync
|
||||
8000B088-8000B0E0 (0058) BugFixes
|
||||
8000B0E0-8000B254 (0174) q8853x send_function_call handler
|
||||
8000B5C8-8000B5DC (0014) BugFixes
|
||||
@@ -27,3 +26,10 @@ Used regions in PSO GC:
|
||||
8000D9A0-8000D9B8 (0018) BugFixes
|
||||
8000DFA0-8000DFE0 (0040) DrawDistance
|
||||
8000E1E0-8000E1FC (001C) BugFixes
|
||||
|
||||
Used regions in PSO XB (40EU):
|
||||
002DB550-002DB600 (B0) handle_0E => EnemyHPBars, FlickeringStatusIcons
|
||||
002DC970-002DCA70 (100) handle_91 => EnemyDamageSync
|
||||
|
||||
Potentially available regions in PSO XB:
|
||||
002BFDB0-002BFE40 (90) handle_03_phase2 (replace handler in table with do_nothing, or just prepend with ret)
|
||||
|
||||
Reference in New Issue
Block a user